internal static DxfBlock FromBuffer(DxfCodePairBufferReader buffer) { if (!buffer.ItemsRemain) { return null; } var block = new DxfBlock(); var readingBlockStart = true; var readingBlockEnd = false; var entities = new List<DxfEntity>(); while (buffer.ItemsRemain) { var pair = buffer.Peek(); if (DxfCodePair.IsSectionEnd(pair)) { // done reading blocks buffer.Advance(); // swallow (0, ENDSEC) break; } else if (IsBlockStart(pair)) { if (readingBlockStart) { // if another block is found, stop reading this one because some blocks don't specify (0, ENDBLK) break; } break; } else if (IsBlockEnd(pair)) { if (!readingBlockStart) throw new DxfReadException("Unexpected block end", pair); readingBlockStart = false; readingBlockEnd = true; buffer.Advance(); // swallow (0, ENDBLK) } else if (pair.Code == 0) { // should be an entity var entity = DxfEntity.FromBuffer(buffer); if (entity != null) { // entity could be null if it's unsupported entities.Add(entity); } } else { // read value pair if (readingBlockStart) { buffer.Advance(); switch (pair.Code) { case 1: block.XrefName = pair.StringValue; break; case 2: block.Name = pair.StringValue; break; case 3: break; case 4: block.Description = pair.StringValue; break; case 5: ((IDxfItemInternal)block).Handle = DxfCommonConverters.UIntHandle(pair.StringValue); break; case 8: block.Layer = pair.StringValue; break; case 10: block.BasePoint = block.BasePoint.WithUpdatedX(pair.DoubleValue); break; case 20: block.BasePoint = block.BasePoint.WithUpdatedY(pair.DoubleValue); break; case 30: block.BasePoint = block.BasePoint.WithUpdatedZ(pair.DoubleValue); break; case 67: block.IsInPaperSpace = DxfCommonConverters.BoolShort(pair.ShortValue); break; case 70: block.Flags = pair.ShortValue; break; case 330: ((IDxfItemInternal)block).OwnerHandle = DxfCommonConverters.UIntHandle(pair.StringValue); break; case DxfCodePairGroup.GroupCodeNumber: var groupName = DxfCodePairGroup.GetGroupName(pair.StringValue); block.ExtensionDataGroups.Add(DxfCodePairGroup.FromBuffer(buffer, groupName)); break; case (int)DxfXDataType.ApplicationName: block.XData = DxfXData.FromBuffer(buffer, pair.StringValue); break; } } else if (readingBlockEnd) { block.EndBlock.ApplyCodePairs(buffer); } else { throw new DxfReadException("Unexpected pair in block", pair); } } } var collected = DxfEntitiesSection.GatherEntities(entities); foreach (var entity in collected) { block.Entities.Add(entity); } return block; }
public DxfFile ReadFile(BinaryReader reader) { // swallow next two characters var sub = reader.ReadChar(); Debug.Assert(sub == 0x1A); var nul = reader.ReadChar(); Debug.Assert(nul == 0x00); DxfPoint?blockBase = null; var entities = new List <DxfEntity>(); var stillReading = true; Action <Func <BinaryReader, DxfEntity> > addEntity = (entityReader) => { var entity = entityReader(reader); AssignCommonValues(entity); entities.Add(entity); }; Func <DxfVertex> getLastVertex = () => entities.LastOrDefault() as DxfVertex; while (stillReading) { var itemType = (DxbItemType)reader.ReadByte(); switch (itemType) { case DxbItemType.Line: addEntity(ReadLine); break; case DxbItemType.Point: addEntity(ReadPoint); break; case DxbItemType.Circle: addEntity(ReadCircle); break; case DxbItemType.Arc: addEntity(ReadArc); break; case DxbItemType.Trace: addEntity(ReadTrace); break; case DxbItemType.Solid: addEntity(ReadSolid); break; case DxbItemType.Seqend: addEntity(ReadSeqend); break; case DxbItemType.Polyline: addEntity(ReadPolyline); break; case DxbItemType.Vertex: addEntity(ReadVertex); break; case DxbItemType.Face: addEntity(ReadFace); break; case DxbItemType.ScaleFactor: _scaleFactor = ReadF(reader); break; case DxbItemType.NewLayer: var sb = new StringBuilder(); for (int b = reader.ReadByte(); b != 0; b = reader.ReadByte()) { sb.Append((char)b); } _layerName = sb.ToString(); break; case DxbItemType.LineExtension: addEntity(ReadLineExtension); break; case DxbItemType.TraceExtension: addEntity(ReadTraceExtension); break; case DxbItemType.BlockBase: var x = ReadN(reader); var y = ReadN(reader); if (blockBase == null && entities.Count == 0) { // only if this is the first item encountered blockBase = new DxfPoint(x, y, 0.0); } break; case DxbItemType.Bulge: { var bulge = ReadU(reader); var lastVertex = getLastVertex(); if (lastVertex != null) { lastVertex.Bulge = bulge; } } break; case DxbItemType.Width: { var startWidth = ReadN(reader); var endWidth = ReadN(reader); var lastVertex = getLastVertex(); if (lastVertex != null) { lastVertex.StartingWidth = startWidth; lastVertex.EndingWidth = endWidth; } } break; case DxbItemType.NumberMode: _isIntegerMode = ReadW(reader) == 0; break; case DxbItemType.NewColor: _color = DxfColor.FromRawValue((short)ReadW(reader)); break; case DxbItemType.LineExtension3D: addEntity(ReadLineExtension3D); break; case 0: stillReading = false; break; } } var file = new DxfFile(); foreach (var section in file.Sections) { section.Clear(); } // collect the entities (e.g., polylines, etc.) entities = DxfEntitiesSection.GatherEntities(entities); if (blockBase != null) { // entities are all contained in a block var block = new DxfBlock(); block.BasePoint = blockBase.GetValueOrDefault(); foreach (var entity in entities) { block.Entities.Add(entity); } file.Blocks.Add(block); } else { // just a normal collection of entities foreach (var entity in entities) { file.Entities.Add(entity); } } return(file); }