public void FieldOffsetsAreAutoAssigned(DbaseField[] fields, ByteOffset[] expected) { var sut = new AnonymousDbaseSchema(fields); Assert.Equal( sut.Fields.Select(field => field.Offset).ToArray(), expected); }
public void ConstructionUsingFieldsHasExpectedResult() { var fields = _fixture.GenerateDbaseFields(); var length = fields.Aggregate(DbaseRecordLength.Initial, (current, field) => current.Plus(field.Length)); var sut = new AnonymousDbaseSchema(fields); Assert.Equal(fields, sut.Fields); Assert.Equal(length, sut.Length); }
public static DbaseFileHeader Read(BinaryReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (reader.ReadByte() != ExpectedDbaseFormat) { throw new DbaseFileHeaderException("The database file type must be 3 (dBase III)."); } var lastUpdated = new DateTime(reader.ReadByte() + 1900, reader.ReadByte(), reader.ReadByte(), 0, 0, 0, DateTimeKind.Unspecified); var recordCount = new DbaseRecordCount(reader.ReadInt32()); var headerLength = reader.ReadInt16(); var fieldCount = (headerLength - HeaderMetaDataSize) / FieldMetaDataSize; if (fieldCount > DbaseSchema.MaximumFieldCount) { throw new DbaseFileHeaderException( $"The database file can not contain more than {DbaseSchema.MaximumFieldCount} fields."); } var recordLength = new DbaseRecordLength(reader.ReadInt16()); reader.ReadBytes(17); var rawCodePage = reader.ReadByte(); if (!DbaseCodePage.TryParse(rawCodePage, out var codePage)) { throw new DbaseFileHeaderException($"The database code page {rawCodePage} is not supported."); } reader.ReadBytes(2); var fields = new DbaseField[fieldCount]; for (var recordFieldIndex = 0; recordFieldIndex < fieldCount; recordFieldIndex++) { fields[recordFieldIndex] = DbaseField.Read(reader); } // verify field offsets are aligned var offset = ByteOffset.Initial; foreach (var field in fields) { if (field.Offset != offset) { throw new DbaseFileHeaderException( $"The field {field.Name} does not have the expected offset {offset} but instead {field.Offset}. Please ensure the offset has been properly set for each field and that the order in which they appear in the record field layout matches their offset."); } offset = field.Offset.Plus(field.Length); } var schema = new AnonymousDbaseSchema(fields); if (recordLength != schema.Length) { throw new DbaseFileHeaderException( $"The database file record length ({recordLength}) does not match the total length of all fields ({schema.Length})."); } if (reader.ReadByte() != Terminator) { throw new DbaseFileHeaderException("The database file header terminator is missing."); } // skip to first record var bytesToSkip = headerLength - (HeaderMetaDataSize + FieldMetaDataSize * fieldCount); reader.ReadBytes(bytesToSkip); return(new DbaseFileHeader(lastUpdated, codePage, recordCount, schema)); }