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

DomCR / ACadSharp / 13096781795

02 Feb 2025 07:35AM UTC coverage: 76.229% (+0.003%) from 76.226%
13096781795

Pull #546

github

web-flow
Merge 88bffdf3e into da8587f47
Pull Request #546: Issue 529 geodata

5358 of 7752 branches covered (69.12%)

Branch coverage included in aggregate %.

129 of 181 new or added lines in 8 files covered. (71.27%)

3 existing lines in 1 file now uncovered.

21413 of 27367 relevant lines covered (78.24%)

39366.42 hits per line

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

90.64
/src/ACadSharp/IO/DXF/DxfStreamReader/DxfObjectsSectionReader.cs
1
using ACadSharp.IO.Templates;
2
using ACadSharp.Objects;
3
using ACadSharp.Objects.Evaluations;
4
using System;
5
using System.Diagnostics;
6
using System.Linq;
7
using static ACadSharp.IO.Templates.CadEvaluationGraphTemplate;
8

9
namespace ACadSharp.IO.DXF
10
{
11
        internal class DxfObjectsSectionReader : DxfSectionReaderBase
12
        {
13
                public delegate bool ReadObjectDelegate<T>(CadTemplate template, DxfMap map) where T : CadObject;
14

15
                public DxfObjectsSectionReader(IDxfStreamReader reader, DxfDocumentBuilder builder)
16
                        : base(reader, builder)
151✔
17
                {
151✔
18
                }
151✔
19

20
                public override void Read()
21
                {
151✔
22
                        //Advance to the first value in the section
23
                        this._reader.ReadNext();
151✔
24

25
                        //Loop until the section ends
26
                        while (this._reader.ValueAsString != DxfFileToken.EndSection)
32,289✔
27
                        {
32,138✔
28
                                CadTemplate template = null;
32,138✔
29

30
                                try
31
                                {
32,138✔
32
                                        template = this.readObject();
32,138✔
33
                                }
32,138✔
34
                                catch (Exception ex)
×
35
                                {
×
36
                                        if (!this._builder.Configuration.Failsafe)
×
37
                                                throw;
×
38

39
                                        this._builder.Notify($"Error while reading an object at line {this._reader.Position}", NotificationType.Error, ex);
×
40

41
                                        while (this._reader.DxfCode != DxfCode.Start)
×
42
                                                this._reader.ReadNext();
×
43
                                }
×
44

45
                                if (template == null)
32,138✔
46
                                        continue;
508✔
47

48
                                //Add the object and the template to the builder
49
                                this._builder.AddTemplate(template);
31,630✔
50
                        }
31,630✔
51
                }
151✔
52

53
                private CadTemplate readObject()
54
                {
32,138✔
55
                        switch (this._reader.ValueAsString)
32,138!
56
                        {
57
                                case DxfFileToken.ObjectDBColor:
58
                                        return this.readObjectCodes<BookColor>(new CadNonGraphicalObjectTemplate(new BookColor()), this.readBookColor);
10✔
59
                                case DxfFileToken.ObjectDictionary:
60
                                        return this.readObjectCodes<CadDictionary>(new CadDictionaryTemplate(), this.readDictionary);
10,234✔
61
                                case DxfFileToken.ObjectDictionaryWithDefault:
62
                                        return this.readObjectCodes<CadDictionaryWithDefault>(new CadDictionaryWithDefaultTemplate(), this.readDictionaryWithDefault);
139✔
63
                                case DxfFileToken.ObjectLayout:
64
                                        return this.readObjectCodes<Layout>(new CadLayoutTemplate(), this.readLayout);
561✔
65
                                case DxfFileToken.ObjectEvalGraph:
66
                                        return this.readObjectCodes<EvaluationGraph>(new CadEvaluationGraphTemplate(), this.readEvaluationGraph);
1✔
67
                                case DxfFileToken.ObjectDictionaryVar:
68
                                        return this.readObjectCodes<DictionaryVariable>(new CadTemplate<DictionaryVariable>(new DictionaryVariable()), this.readObjectSubclassMap);
1,904✔
69
                                case DxfFileToken.ObjectPdfDefinition:
70
                                        return this.readObjectCodes<PdfUnderlayDefinition>(new CadNonGraphicalObjectTemplate(new PdfUnderlayDefinition()), this.readObjectSubclassMap);
×
71
                                case DxfFileToken.ObjectSortEntsTable:
72
                                        return this.readSortentsTable();
246✔
73
                                case DxfFileToken.ObjectGeoData:
74
                                        return this.readObjectCodes<GeoData>(new CadGeoDataTemplate(), this.readGeoData);
1✔
75
                                case DxfFileToken.ObjectScale:
76
                                        return this.readObjectCodes<Scale>(new CadTemplate<Scale>(new Scale()), this.readScale);
4,791✔
77
                                case DxfFileToken.ObjectTableContent:
78
                                        return this.readObjectCodes<TableContent>(new CadTableContentTemplate(), this.readTableContent);
121✔
79
                                case DxfFileToken.ObjectVisualStyle:
80
                                        return this.readObjectCodes<VisualStyle>(new CadTemplate<VisualStyle>(new VisualStyle()), this.readVisualStyle);
3,336✔
81
                                case DxfFileToken.ObjectXRecord:
82
                                        return this.readObjectCodes<XRecord>(new CadXRecordTemplate(), this.readXRecord);
7,744✔
83
                                default:
84
                                        DxfMap map = DxfMap.Create<CadObject>();
3,050✔
85
                                        CadUnknownNonGraphicalObjectTemplate unknownEntityTemplate = null;
3,050✔
86
                                        if (this._builder.DocumentToBuild.Classes.TryGetByName(this._reader.ValueAsString, out Classes.DxfClass dxfClass))
3,050✔
87
                                        {
2,542✔
88
                                                this._builder.Notify($"NonGraphicalObject not supported read as an UnknownNonGraphicalObject: {this._reader.ValueAsString}", NotificationType.NotImplemented);
2,542✔
89
                                                unknownEntityTemplate = new CadUnknownNonGraphicalObjectTemplate(new UnknownNonGraphicalObject(dxfClass));
2,542✔
90
                                        }
2,542✔
91
                                        else
92
                                        {
508✔
93
                                                this._builder.Notify($"UnknownNonGraphicalObject not supported: {this._reader.ValueAsString}", NotificationType.NotImplemented);
508✔
94
                                        }
508✔
95

96
                                        this._reader.ReadNext();
3,050✔
97

98
                                        do
99
                                        {
174,262✔
100
                                                if (unknownEntityTemplate != null && this._builder.KeepUnknownEntities)
174,262✔
101
                                                {
15,600✔
102
                                                        this.readCommonCodes(unknownEntityTemplate, out bool isExtendedData, map);
15,600✔
103
                                                        if (isExtendedData)
15,600✔
104
                                                                continue;
26✔
105
                                                }
15,574✔
106

107
                                                this._reader.ReadNext();
174,236✔
108
                                        }
174,236✔
109
                                        while (this._reader.DxfCode != DxfCode.Start);
174,262✔
110

111
                                        return unknownEntityTemplate;
3,050✔
112
                        }
113
                }
32,138✔
114

115
                protected CadTemplate readObjectCodes<T>(CadTemplate template, ReadObjectDelegate<T> readObject)
116
                        where T : CadObject
117
                {
28,842✔
118
                        this._reader.ReadNext();
28,842✔
119

120
                        DxfMap map = DxfMap.Create<T>();
28,842✔
121

122
                        while (this._reader.DxfCode != DxfCode.Start)
879,086✔
123
                        {
850,244✔
124
                                if (!readObject(template, map))
850,244✔
125
                                {
447,171✔
126
                                        this.readCommonCodes(template, out bool isExtendedData, map);
447,171✔
127
                                        if (isExtendedData)
447,171✔
128
                                                continue;
3,186✔
129
                                }
443,985✔
130

131
                                if (this._reader.DxfCode != DxfCode.Start)
847,058✔
132
                                        this._reader.ReadNext();
839,313✔
133
                        }
847,058✔
134

135
                        return template;
28,842✔
136
                }
28,842✔
137

138
                private bool readObjectSubclassMap(CadTemplate template, DxfMap map)
139
                {
11,424✔
140
                        switch (this._reader.Code)
11,424✔
141
                        {
142
                                default:
143
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
11,424✔
144
                        }
145
                }
11,424✔
146

147
                private bool readPlotSettings(CadTemplate template, DxfMap map)
148
                {
17,686✔
149
                        switch (this._reader.Code)
17,686✔
150
                        {
151
                                default:
152
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.PlotSettings]);
17,686✔
153
                        }
154
                }
17,686✔
155

156
                private bool readEvaluationGraph(CadTemplate template, DxfMap map)
157
                {
8✔
158
                        CadEvaluationGraphTemplate tmp = template as CadEvaluationGraphTemplate;
8✔
159
                        EvaluationGraph evGraph = tmp.CadObject;
8✔
160

161
                        switch (this._reader.Code)
8✔
162
                        {
163
                                case 91:
164
                                        while (this._reader.Code == 91)
13✔
165
                                        {
12✔
166
                                                GraphNodeTemplate nodeTemplate = new GraphNodeTemplate();
12✔
167
                                                EvaluationGraph.Node node = nodeTemplate.Node;
12✔
168

169
                                                node.Index = this._reader.ValueAsInt;
12✔
170

171
                                                this._reader.ExpectedCode(93);
12✔
172
                                                node.Flags = this._reader.ValueAsInt;
12✔
173

174
                                                this._reader.ExpectedCode(95);
12✔
175
                                                node.NextNodeIndex = this._reader.ValueAsInt;
12✔
176

177
                                                this._reader.ExpectedCode(360);
12✔
178
                                                nodeTemplate.ExpressionHandle = this._reader.ValueAsHandle;
12✔
179

180
                                                this._reader.ExpectedCode(92);
12✔
181
                                                node.Data1 = this._reader.ValueAsInt;
12✔
182
                                                this._reader.ExpectedCode(92);
12✔
183
                                                node.Data2 = this._reader.ValueAsInt;
12✔
184
                                                this._reader.ExpectedCode(92);
12✔
185
                                                node.Data3 = this._reader.ValueAsInt;
12✔
186
                                                this._reader.ExpectedCode(92);
12✔
187
                                                node.Data4 = this._reader.ValueAsInt;
12✔
188

189
                                                this._reader.ReadNext();
12✔
190

191
                                                tmp.NodeTemplates.Add(nodeTemplate);
12✔
192
                                        }
12✔
193

194
                                        return this.checkObjectEnd(template, map, this.readEvaluationGraph);
1✔
195
                                case 92:
196
                                        //Edges
197
                                        while (this._reader.Code == 92)
11✔
198
                                        {
10✔
199
                                                this._reader.ExpectedCode(93);
10✔
200
                                                this._reader.ExpectedCode(94);
10✔
201
                                                this._reader.ExpectedCode(91);
10✔
202
                                                this._reader.ExpectedCode(91);
10✔
203
                                                this._reader.ExpectedCode(92);
10✔
204
                                                this._reader.ExpectedCode(92);
10✔
205
                                                this._reader.ExpectedCode(92);
10✔
206
                                                this._reader.ExpectedCode(92);
10✔
207
                                                this._reader.ExpectedCode(92);
10✔
208

209
                                                this._reader.ReadNext();
10✔
210
                                        }
10✔
211

212
                                        return this.checkObjectEnd(template, map, this.readEvaluationGraph);
1✔
213
                                default:
214
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.EvalGraph]);
6✔
215
                        }
216
                }
8✔
217

218
                private bool readLayout(CadTemplate template, DxfMap map)
219
                {
36,027✔
220
                        CadLayoutTemplate tmp = template as CadLayoutTemplate;
36,027✔
221

222
                        switch (this._reader.Code)
36,027✔
223
                        {
224
                                case 330:
225
                                        tmp.PaperSpaceBlockHandle = this._reader.ValueAsHandle;
1,122✔
226
                                        return true;
1,122✔
227
                                case 331:
228
                                        tmp.LasActiveViewportHandle = (this._reader.ValueAsHandle);
499✔
229
                                        return true;
499✔
230
                                default:
231
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Layout]))
34,406✔
232
                                        {
17,686✔
233
                                                return this.readPlotSettings(template, map);
17,686✔
234
                                        }
235
                                        return true;
16,720✔
236
                        }
237
                }
36,027✔
238

239
                private bool readGeoData(CadTemplate template, DxfMap map)
240
                {
46✔
241
                        CadGeoDataTemplate tmp = template as CadGeoDataTemplate;
46✔
242

243
                        switch (this._reader.Code)
46✔
244
                        {
245
                                // Number of Geo-Mesh points
246
                                case 93:
247
                                        var npts = this._reader.ValueAsInt;
1✔
248
                                        for (int i = 0; i < npts; i++)
26✔
249
                                        {
12✔
250
                                                this._reader.ReadNext();
12✔
251
                                                Debug.Assert(this._reader.Code == 13);
12✔
252
                                                double sourceX = this._reader.ValueAsDouble;
12✔
253
                                                this._reader.ReadNext();
12✔
254
                                                Debug.Assert(this._reader.Code == 23);
12✔
255
                                                double sourceY = this._reader.ValueAsDouble;
12✔
256

257
                                                this._reader.ReadNext();
12✔
258
                                                Debug.Assert(this._reader.Code == 14);
12✔
259
                                                double destX = this._reader.ValueAsDouble;
12✔
260
                                                this._reader.ReadNext();
12✔
261
                                                Debug.Assert(this._reader.Code == 24);
12✔
262
                                                double destY = this._reader.ValueAsDouble;
12✔
263

264
                                                tmp.CadObject.Points.Add(new GeoData.GeoMeshPoint
12✔
265
                                                {
12✔
266
                                                        Source = new CSMath.XY(sourceX, sourceY),
12✔
267
                                                        Destination = new CSMath.XY(destX, destY)
12✔
268
                                                });
12✔
269
                                        }
12✔
270
                                        return true;
1✔
271
                                // Number of Geo-Mesh points
272
                                case 96:
273
                                        var nfaces = this._reader.ValueAsInt;
1✔
274
                                        for (int i = 0; i < nfaces; i++)
2!
NEW
275
                                        {
×
NEW
276
                                                this._reader.ReadNext();
×
NEW
277
                                                Debug.Assert(this._reader.Code == 97);
×
NEW
278
                                                int index1 = this._reader.ValueAsInt;
×
NEW
279
                                                this._reader.ReadNext();
×
NEW
280
                                                Debug.Assert(this._reader.Code == 98);
×
NEW
281
                                                int index2 = this._reader.ValueAsInt;
×
NEW
282
                                                this._reader.ReadNext();
×
NEW
283
                                                Debug.Assert(this._reader.Code == 99);
×
NEW
284
                                                int index3 = this._reader.ValueAsInt;
×
285

NEW
286
                                                tmp.CadObject.Faces.Add(new GeoData.GeoMeshFace
×
NEW
287
                                                {
×
NEW
288
                                                        Index1 = index1,
×
NEW
289
                                                        Index2 = index2,
×
NEW
290
                                                        Index3 = index3
×
NEW
291
                                                });
×
NEW
292
                                        }
×
293
                                        return true;
1✔
294
                                case 303:
295
                                        tmp.CadObject.CoordinateSystemDefinition += this._reader.ValueAsString;
12✔
296
                                        return true;
12✔
297
                                default:
298
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
32✔
299
                        }
300
                }
46✔
301

302
                private bool readScale(CadTemplate template, DxfMap map)
303
                {
42,915✔
304
                        switch (this._reader.Code)
42,915✔
305
                        {
306
                                // Undocumented codes
307
                                case 70:
308
                                        //Always 0
309
                                        return true;
4,791✔
310
                                default:
311
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Scale]);
38,124✔
312
                        }
313
                }
42,915✔
314

315
                private bool readTableContent(CadTemplate template, DxfMap map)
316
                {
367,117✔
317
                        switch (this._reader.Code)
367,117✔
318
                        {
319
                                default:
320
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.TableContent]);
367,117✔
321
                        }
322
                }
367,117✔
323

324
                private bool readVisualStyle(CadTemplate template, DxfMap map)
325
                {
261,402✔
326
                        switch (this._reader.Code)
261,402✔
327
                        {
328
                                // Undocumented codes
329
                                case 176:
330
                                case 177:
331
                                case 420:
332
                                        return true;
94,282✔
333
                                default:
334
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.VisualStyle]);
167,120✔
335
                        }
336
                }
261,402✔
337

338
                private bool readXRecord(CadTemplate template, DxfMap map)
339
                {
30,256✔
340
                        CadXRecordTemplate tmp = template as CadXRecordTemplate;
30,256✔
341

342
                        switch (this._reader.Code)
30,256✔
343
                        {
344
                                case 100 when this._reader.ValueAsString == DxfSubclassMarker.XRecord:
7,744✔
345
                                        this.readXRecordEntries(tmp);
7,744✔
346
                                        return true;
7,744✔
347
                                default:
348
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.XRecord]);
22,512✔
349
                        }
350
                }
30,256✔
351

352
                private void readXRecordEntries(CadXRecordTemplate template)
353
                {
7,744✔
354
                        this._reader.ReadNext();
7,744✔
355

356
                        while (this._reader.DxfCode != DxfCode.Start)
530,937✔
357
                        {
523,193✔
358
                                switch (this._reader.GroupCodeValue)
523,193!
359
                                {
360
                                        case GroupCodeValueType.Handle:
361
                                                template.AddHandleReference(this._reader.Code, this._reader.ValueAsHandle);
×
362
                                                break;
×
363
                                        default:
364
                                                template.CadObject.CreateEntry(this._reader.Code, this._reader.Value);
523,193✔
365
                                                break;
523,193✔
366
                                }
367

368
                                this._reader.ReadNext();
523,193✔
369
                        }
523,193✔
370
                }
7,744✔
371

372
                private bool readBookColor(CadTemplate template, DxfMap map)
373
                {
70✔
374
                        CadNonGraphicalObjectTemplate tmp = template as CadNonGraphicalObjectTemplate;
70✔
375
                        BookColor color = tmp.CadObject as BookColor;
70✔
376

377
                        switch (this._reader.Code)
70✔
378
                        {
379
                                case 430:
380
                                        color.Name = this._reader.ValueAsString;
8✔
381
                                        return true;
8✔
382
                                default:
383
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.DbColor]);
62✔
384
                        }
385
                }
70✔
386

387
                private bool readDictionary(CadTemplate template, DxfMap map)
388
                {
100,841✔
389
                        CadDictionaryTemplate tmp = template as CadDictionaryTemplate;
100,841✔
390
                        CadDictionary cadDictionary = tmp.CadObject;
100,841✔
391

392
                        switch (this._reader.Code)
100,841✔
393
                        {
394
                                case 280:
395
                                        cadDictionary.HardOwnerFlag = this._reader.ValueAsBool;
6,605✔
396
                                        return true;
6,605✔
397
                                case 281:
398
                                        cadDictionary.ClonningFlags = (DictionaryCloningFlags)this._reader.Value;
10,373✔
399
                                        return true;
10,373✔
400
                                case 3:
401
                                        tmp.Entries.Add(this._reader.ValueAsString, null);
24,371✔
402
                                        return true;
24,371✔
403
                                case 350: // Soft-owner ID/handle to entry object 
404
                                case 360: // Hard-owner ID/handle to entry object
405
                                        tmp.Entries[tmp.Entries.LastOrDefault().Key] = this._reader.ValueAsHandle;
24,371✔
406
                                        return true;
24,371✔
407
                                default:
408
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Dictionary]);
35,121✔
409
                        }
410
                }
100,841✔
411

412
                private bool readDictionaryWithDefault(CadTemplate template, DxfMap map)
413
                {
1,251✔
414
                        CadDictionaryWithDefaultTemplate tmp = template as CadDictionaryWithDefaultTemplate;
1,251✔
415

416
                        switch (this._reader.Code)
1,251✔
417
                        {
418
                                case 340:
419
                                        tmp.DefaultEntryHandle = this._reader.ValueAsHandle;
139✔
420
                                        return true;
139✔
421
                                default:
422
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.DictionaryWithDefault]))
1,112!
423
                                        {
1,112✔
424
                                                return this.readDictionary(template, map);
1,112✔
425
                                        }
426
                                        return true;
×
427
                        }
428
                }
1,251✔
429

430
                private CadTemplate readSortentsTable()
431
                {
246✔
432
                        SortEntitiesTable sortTable = new SortEntitiesTable();
246✔
433
                        CadSortensTableTemplate template = new CadSortensTableTemplate(sortTable);
246✔
434

435
                        //Jump the 0 marker
436
                        this._reader.ReadNext();
246✔
437

438
                        this.readCommonObjectData(template);
246✔
439

440
                        System.Diagnostics.Debug.Assert(DxfSubclassMarker.SortentsTable == this._reader.ValueAsString);
246✔
441

442
                        //Jump the 100 marker
443
                        this._reader.ReadNext();
246✔
444

445
                        (ulong?, ulong?) pair = (null, null);
246✔
446

447
                        while (this._reader.DxfCode != DxfCode.Start)
2,492✔
448
                        {
2,246✔
449
                                switch (this._reader.Code)
2,246!
450
                                {
451
                                        case 5:
452
                                                pair.Item1 = this._reader.ValueAsHandle;
1,000✔
453
                                                break;
1,000✔
454
                                        case 330:
455
                                                template.BlockOwnerHandle = this._reader.ValueAsHandle;
246✔
456
                                                break;
246✔
457
                                        case 331:
458
                                                pair.Item2 = this._reader.ValueAsHandle;
1,000✔
459
                                                break;
1,000✔
460
                                        default:
461
                                                this._builder.Notify($"Group Code not handled {this._reader.GroupCodeValue} for {typeof(SortEntitiesTable)}, code : {this._reader.Code} | value : {this._reader.ValueAsString}");
×
462
                                                break;
×
463
                                }
464

465
                                if (pair.Item1.HasValue && pair.Item2.HasValue)
2,246✔
466
                                {
1,000✔
467
                                        template.Values.Add((pair.Item1.Value, pair.Item2.Value));
1,000✔
468
                                        pair = (null, null);
1,000✔
469
                                }
1,000✔
470

471
                                this._reader.ReadNext();
2,246✔
472
                        }
2,246✔
473

474
                        return template;
246✔
475
                }
246✔
476
        }
477
}
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