public ZipArchiveProblems Validate(ZipArchiveEntry entry, IEnumerator <ShapeRecord> records)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }
            if (records == null)
            {
                throw new ArgumentNullException(nameof(records));
            }

            var problems     = ZipArchiveProblems.None;
            var recordNumber = RecordNumber.Initial;

            try
            {
                var moved = records.MoveNext();
                if (moved)
                {
                    while (moved)
                    {
                        var record = records.Current;
                        if (record != null)
                        {
                            var recordContext = entry.AtShapeRecord(record.Header.RecordNumber);
                            if (record.Content.ShapeType != ShapeType.Point)
                            {
                                problems += recordContext.ShapeRecordShapeTypeMismatch(
                                    ShapeType.Point,
                                    record.Content.ShapeType);
                            }
                            else if (record.Content is PointShapeContent content)
                            {
                                if (!GeometryTranslator.ToGeometryPoint(content.Shape).IsValid)
                                {
                                    problems += recordContext.ShapeRecordGeometryMismatch();
                                }
                            }
                            recordNumber = record.Header.RecordNumber.Next();
                        }
                        else
                        {
                            recordNumber = recordNumber.Next();
                        }

                        moved = records.MoveNext();
                    }
                }
                else
                {
                    problems += entry.HasNoShapeRecords();
                }
            }
            catch (Exception exception)
            {
                problems += entry.AtShapeRecord(recordNumber).HasShapeRecordFormatError(exception);
            }

            return(problems);
        }
        public void ValidateWithNullRecordsReturnsExpectedResult()
        {
            var records = _fixture
                          .CreateMany <ShapeRecord>(new Random().Next(1, 5))
                          .Select((record, index) => index == 0
                    ? NullShapeContent.Instance.RecordAs(new RecordNumber(index + 1))
                    : record.Content.RecordAs(new RecordNumber(index + 1)))
                          .GetEnumerator();

            var result = _sut.Validate(_entry, records);

            Assert.Equal(
                ZipArchiveProblems.Single(
                    _entry
                    .AtShapeRecord(RecordNumber.Initial)
                    .ShapeRecordShapeTypeMismatch(
                        ShapeType.Point,
                        ShapeType.NullShape)
                    ),
                result);
        }
        public ZipArchiveProblems Validate(ZipArchiveEntry entry, IEnumerator <ShapeRecord> records)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }
            if (records == null)
            {
                throw new ArgumentNullException(nameof(records));
            }

            var problems     = ZipArchiveProblems.None;
            var recordNumber = RecordNumber.Initial;

            try
            {
                var moved = records.MoveNext();
                if (moved)
                {
                    while (moved)
                    {
                        var record = records.Current;
                        if (record != null)
                        {
                            var recordContext = entry.AtShapeRecord(record.Header.RecordNumber);
                            if (record.Content.ShapeType != ShapeType.PolyLineM)
                            {
                                problems += recordContext.ShapeRecordShapeTypeMismatch(
                                    ShapeType.PolyLineM,
                                    record.Content.ShapeType);
                            }
                            else if (record.Content is PolyLineMShapeContent content)
                            {
                                var shape = GeometryTranslator.ToGeometryMultiLineString(content.Shape);
                                if (!shape.IsValid)
                                {
                                    problems += recordContext.ShapeRecordGeometryMismatch();
                                }
                                else
                                {
                                    var lines = shape
                                                .Geometries
                                                .OfType <LineString>()
                                                .ToArray();
                                    if (lines.Length != 1)
                                    {
                                        problems += recordContext.ShapeRecordGeometryLineCountMismatch(
                                            1,
                                            lines.Length);
                                    }
                                    else
                                    {
                                        var line = lines[0];
                                        if (LineStringExtensions.SelfOverlaps(line))
                                        {
                                            problems += recordContext.ShapeRecordGeometrySelfOverlaps();
                                        }
                                        else if (LineStringExtensions.SelfIntersects(line))
                                        {
                                            problems += recordContext.ShapeRecordGeometrySelfIntersects();
                                        }
                                    }
                                }
                            }
                            recordNumber = record.Header.RecordNumber.Next();
                        }
                        else
                        {
                            recordNumber = recordNumber.Next();
                        }

                        moved = records.MoveNext();
                    }
                }
                else
                {
                    problems += entry.HasNoShapeRecords();
                }
            }
            catch (Exception exception)
            {
                problems += entry.AtShapeRecord(recordNumber).HasShapeRecordFormatError(exception);
            }

            return(problems);
        }