Skip to content

Commit

Permalink
Merge pull request #74 from DomCR/issue-63_slow-dwg-reader
Browse files Browse the repository at this point in the history
Issue 63 Slow Read
  • Loading branch information
DomCR authored Dec 1, 2022
2 parents a014479 + dd6349d commit b30dca9
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 9 deletions.
73 changes: 73 additions & 0 deletions ACadSharp.Tests/IO/StressSamplesReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using ACadSharp.IO;
using System.IO;
using System.Linq;
using Xunit;
using Xunit.Abstractions;

namespace ACadSharp.Tests.IO
{
public class StressSamplesReader : IOTestsBase
{
public static TheoryData<string> UserDwgFilePaths { get; }

public static TheoryData<string> UserDxfFiles { get; }

static StressSamplesReader()
{
string path = Path.Combine(_samplesFolder, "local", "stress");
UserDwgFilePaths = new TheoryData<string>();
UserDxfFiles = new TheoryData<string>();

if (!Directory.Exists(path))
{
UserDwgFilePaths.Add(string.Empty);
UserDxfFiles.Add(string.Empty);
return;
}

foreach (string file in Directory.GetFiles(path, $"*.dwg"))
{
UserDwgFilePaths.Add(file);
}

foreach (string file in Directory.GetFiles(path, $"*.dxf"))
{
UserDxfFiles.Add(file);
}

if (!UserDwgFilePaths.Any())
{
UserDwgFilePaths.Add(string.Empty);
}

if (!UserDxfFiles.Any())
{
UserDxfFiles.Add(string.Empty);
}
}

public StressSamplesReader(ITestOutputHelper output) : base(output)
{
}

[Theory]
[MemberData(nameof(UserDwgFilePaths))]
public void ReadUserDwg(string test)
{
if (string.IsNullOrEmpty(test))
return;

CadDocument doc = DwgReader.Read(test, this.onNotification);
}

[Theory]
[MemberData(nameof(UserDxfFiles))]
public void ReadUserDxf(string test)
{
if (string.IsNullOrEmpty(test))
return;

CadDocument doc = DxfReader.Read(test, this.onNotification);
}
}
}
30 changes: 23 additions & 7 deletions ACadSharp/IO/DWG/DwgObjectSectionReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ internal class DwgObjectSectionReader : DwgSectionReader
/// </summary>
private Queue<ulong> _handles;

private readonly Dictionary<ulong, ObjectType> _readedObjects = new Dictionary<ulong, ObjectType>();

private readonly Dictionary<ulong, long> _map;

private readonly Dictionary<short, DxfClass> _classes;

private DwgDocumentBuilder _builder;
Expand Down Expand Up @@ -79,13 +82,14 @@ internal class DwgObjectSectionReader : DwgSectionReader
private readonly Stream _crcStream;
private readonly byte[] _crcStreamBuffer;

private readonly byte[] _buffer;

public DwgObjectSectionReader(
ACadVersion version,
DwgDocumentBuilder builder,
IDwgStreamReader reader,
Queue<ulong> handles,
Dictionary<ulong, long> handleMap,
DxfClassCollection classes) : base(version)
DxfClassCollection classes) : base(builder.DocumentToBuild.Header.Version)
{
this._builder = builder;

Expand Down Expand Up @@ -122,13 +126,17 @@ public void Read()
ulong handle = this._handles.Dequeue();

//Check if the handle has already been read
if (!this._map.TryGetValue(handle, out long offset) || this._builder.TryGetObjectTemplate(handle, out CadTemplate _))
if (!this._map.TryGetValue(handle, out long offset) ||
this._builder.TryGetObjectTemplate(handle, out CadTemplate _) ||
this._readedObjects.ContainsKey(handle))
{
continue;
}

//Get the object type
ObjectType type = this.getEntityType(offset);
//Save the object to avoid infinite loops while reading
_readedObjects.Add(handle, type);

CadTemplate template = null;

Expand All @@ -149,7 +157,7 @@ public void Read()
//Add the template to the list to be processed
if (template == null)
{
continue;

}
else if (template is ICadTableTemplate tableTemplate)
{
Expand Down Expand Up @@ -197,6 +205,7 @@ private ObjectType getEntityType(long offset)
this._objectInitialPos = this._objectReader.PositionInBits();
type = this._objectReader.ReadObjectType();


//Create a handler section reader
this._handlesReader = DwgStreamReader.GetStreamHandler(this._version, new MemoryStream(this._crcStreamBuffer));
this._handlesReader.SetPositionInBits((long)handleSectionOffset);
Expand Down Expand Up @@ -244,9 +253,14 @@ private ulong handleReference(ulong handle)
//Read the handle
ulong value = this._handlesReader.HandleReference(handle);

if (!this._builder.TryGetObjectTemplate(value, out CadTemplate _) && !this._handles.Contains(value) && value != 0)
if (!this._builder.TryGetObjectTemplate(value, out CadTemplate _) &&
!this._handles.Contains(value) &&
value != 0 &&
!this._readedObjects.ContainsKey(handle))
{
//Add the value to the handles queue to be processed
this._handles.Enqueue(value);
}

return value;
}
Expand Down Expand Up @@ -343,8 +357,10 @@ private void readCommonEntityData(CadEntityTemplate template)
}
else if (!this.R2004Plus)
{
this._handles.Enqueue(entity.Handle - 1UL);
this._handles.Enqueue(entity.Handle + 1UL);
if (!this._readedObjects.ContainsKey(entity.Handle - 1UL))
this._handles.Enqueue(entity.Handle - 1UL);
if (!this._readedObjects.ContainsKey(entity.Handle + 1UL))
this._handles.Enqueue(entity.Handle + 1UL);
}

//Color CMC(B) 62
Expand Down
1 change: 0 additions & 1 deletion ACadSharp/IO/DWG/DwgReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,6 @@ private void readObjects()
.Select(a => a.Value));

DwgObjectSectionReader sectionReader = new DwgObjectSectionReader(
this._fileHeader.AcadVersion,
this._builder,
sreader,
objectHandles,
Expand Down
2 changes: 1 addition & 1 deletion ACadSharp/IO/Templates/DwgColorTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public override void Build(CadDocumentBuilder builder)
{
base.Build(builder);

throw new NotImplementedException();
//throw new NotImplementedException();
}

public class DwgColor : CadObject
Expand Down

0 comments on commit b30dca9

Please sign in to comment.