Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions FileHelpers.Tests/Data/Good/CustomersFixedOffset.txt

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions FileHelpers.Tests/Data/Good/CustomersFixedOffsetExact.txt

Large diffs are not rendered by default.

830 changes: 830 additions & 0 deletions FileHelpers.Tests/Data/Good/OrdersFixedOffset.txt

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion FileHelpers.Tests/FileHelpers.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>net45;netcoreapp3.1;net6.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>FileHelpers.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
Expand All @@ -23,6 +23,12 @@
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="FSharp.Compiler.Service" Version="39.0.0" />
<PackageReference Include="System.Drawing.Common" Version="5.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\FileHelpers.ExcelNPOIStorage\FileHelpers.ExcelNPOIStorage.csproj" />
<ProjectReference Include="..\FileHelpers\FileHelpers.csproj" />
Expand All @@ -38,4 +44,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<None Remove="Data\Good\CustomersFixedOffset.txt" />
<None Remove="Data\Good\CustomersFixedOffsetExact.txt" />
<None Remove="Data\Good\OrdersFixedOffset.txt" />
</ItemGroup>
</Project>
12 changes: 12 additions & 0 deletions FileHelpers.Tests/Tests/Common/Customers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ public void Fixed()
RunTests<CustomersFixed>("Good", "CustomersFixed.txt");
}

[Test]
public void Offset()
{
RunTests<CustomersFixedOffset>("Good", "CustomersFixedOffset.txt");
}

[Test]
public void OffsetExact()
{
RunTests<CustomersFixedOffset>("Good", "CustomersFixedOffsetExact.txt");
}

[Test]
public void Tab()
{
Expand Down
7 changes: 7 additions & 0 deletions FileHelpers.Tests/Tests/Common/Orders.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using FileHelpers.Tests.Types.Orders;
using NUnit.Framework;

namespace FileHelpers.Tests.CommonTests
Expand All @@ -22,6 +23,12 @@ public void Fixed()
RunTests<OrdersFixed>("Good", "OrdersFixed.txt");
}

[Test]
public void Offset()
{
RunTests<OrdersFixedOffset>("Good", "OrdersFixedOffset.txt");
}

[Test]
public void Tab()
{
Expand Down
51 changes: 51 additions & 0 deletions FileHelpers.Tests/Types/Customers/CustomersFixedOffset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace FileHelpers.Tests
{
/// <summary>
/// Sample fixed length record layout
/// </summary>
[FixedLengthRecord]
public class CustomersFixedOffset
{
/// <summary>
/// Customer id is first 11 characters
/// </summary>
[FieldFixedLength(11, Offset = 4)]
public string CustomerID;

/// <summary>
/// Company name is from position 12 through 50
/// </summary>
[FieldFixedLength(50 - 12)]
public string CompanyName;

/// <summary>
/// Contact name is from position 50 through 72
/// </summary>
[FieldFixedLength(72 - 50)]
public string ContactName;

/// <summary>
/// Contact title is position 72 through 110
/// </summary>
[FieldFixedLength(110 - 72)]
public string ContactTitle;

/// <summary>
/// Address is from 110 through 151
/// </summary>
[FieldFixedLength(151 - 110)]
public string Address;

/// <summary>
/// City is position 151 through 169
/// </summary>
[FieldFixedLength(169 - 151)]
public string City;

/// <summary>
/// Country is just last 15 characters, no magic subtractions
/// </summary>
[FieldFixedLength(15)]
public string Country;
}
}
38 changes: 38 additions & 0 deletions FileHelpers.Tests/Types/Orders/OrdersFixedOffset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace FileHelpers.Tests.Types.Orders
{
[FixedLengthRecord]
public class OrdersFixedOffset
{
[FieldFixedLength(7)]
public int OrderID;

[FieldFixedLength(12, Offset = 2)]
public string CustomerID;

[FieldFixedLength(3, Offset = 3)]
public int EmployeeID;

[FieldFixedLength(10)]
public DateTime OrderDate;

[FieldFixedLength(10)]
public DateTime RequiredDate;

[FieldFixedLength(10)]
[FieldNullValue(typeof(DateTime), "2005-1-1")]
public DateTime ShippedDate;

[FieldFixedLength(3)]
public int ShipVia;

[FieldFixedLength(10)]
public decimal Freight;
}
}
6 changes: 6 additions & 0 deletions FileHelpers.lutconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<LUTConfig Version="1.0">
<Repository />
<ParallelBuilds>true</ParallelBuilds>
<ParallelTestRuns>true</ParallelTestRuns>
<TestCaseTimeout>180000</TestCaseTimeout>
</LUTConfig>
5 changes: 5 additions & 0 deletions FileHelpers/Attributes/FieldFixedLengthAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public sealed class FieldFixedLengthAttribute : FieldAttribute
/// <summary>Length of this Fixed Length field.</summary>
public int Length { get; private set; }

/// <summary>
/// Length to offset the field by.
/// </summary>
public int Offset { get; set; }

/// <summary>
/// Overflow behavior for this Fixed Length field.
/// By default uses <code>OverflowMode.DiscardEnd</code>.
Expand Down
12 changes: 6 additions & 6 deletions FileHelpers/Core/RecordInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private RecordInfo(Type recordType)
/// </summary>
private void InitRecordFields()
{
var recordAttribute = Attributes.GetFirstInherited<TypedRecordAttribute>(RecordType);
var recordAttribute = Core.Attributes.GetFirstInherited<TypedRecordAttribute>(RecordType);

if (recordAttribute == null) {
throw new BadUsageException($"The record class {RecordType.Name} must be marked with the [DelimitedRecord] or [FixedLengthRecord] Attribute");
Expand All @@ -143,23 +143,23 @@ private void InitRecordFields()
throw new BadUsageException($"The record class {RecordType.Name} needs a constructor with no args (public or private)");
}

Attributes.WorkWithFirst<IgnoreFirstAttribute>(
Core.Attributes.WorkWithFirst<IgnoreFirstAttribute>(
RecordType,
a => IgnoreFirst = a.NumberOfLines);

Attributes.WorkWithFirst<IgnoreLastAttribute>(
Core.Attributes.WorkWithFirst<IgnoreLastAttribute>(
RecordType,
a => IgnoreLast = a.NumberOfLines);

Attributes.WorkWithFirst<IgnoreEmptyLinesAttribute>(
Core.Attributes.WorkWithFirst<IgnoreEmptyLinesAttribute>(
RecordType,
a => {
IgnoreEmptyLines = true;
IgnoreEmptySpaces = a.IgnoreSpaces;
});

#pragma warning disable CS0618 // Type or member is obsolete
Attributes.WorkWithFirst<IgnoreCommentedLinesAttribute>(
Core.Attributes.WorkWithFirst<IgnoreCommentedLinesAttribute>(
#pragma warning restore CS0618 // Type or member is obsolete
RecordType,
a => {
Expand All @@ -168,7 +168,7 @@ private void InitRecordFields()
CommentAnyPlace = a.AnyPlace;
});

Attributes.WorkWithFirst<ConditionalRecordAttribute>(
Core.Attributes.WorkWithFirst<ConditionalRecordAttribute>(
RecordType,
a => {
RecordCondition = a.Condition;
Expand Down
1 change: 1 addition & 0 deletions FileHelpers/Fields/FieldBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAtt
attbFixedLength.Length,
attbFixedLength.OverflowMode,
attbAlign,
attbFixedLength.Offset,
recordAttribute.DefaultCultureName);
((FixedLengthField)res).FixedMode = ((FixedLengthRecordAttribute)recordAttribute).FixedMode;
}
Expand Down
16 changes: 14 additions & 2 deletions FileHelpers/Fields/FixedLengthField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public sealed class FixedLengthField
/// </summary>
internal int FieldLength { get; private set; }


/// <summary>
/// Length to offset this field in the record
/// </summary>
internal int FieldOffset { get; private set; }

/// <summary>
/// Alignment of this record
/// </summary>
Expand Down Expand Up @@ -51,12 +57,13 @@ private FixedLengthField() {}
/// <param name="overflowMode">Overflow mode of this field</param>
/// <param name="align">Alignment, left or right</param>
/// <param name="defaultCultureName">Default culture name used for each properties if no converter is specified otherwise. If null, the default decimal separator (".") will be used.</param>
internal FixedLengthField(FieldInfo fi, int length, OverflowMode overflowMode, FieldAlignAttribute align, string defaultCultureName=null)
internal FixedLengthField(FieldInfo fi, int length, OverflowMode overflowMode, FieldAlignAttribute align, int offset, string defaultCultureName=null)
: base(fi, defaultCultureName)
{
FixedMode = FixedMode.ExactLength;
OverflowMode = overflowMode;
Align = new FieldAlignAttribute(AlignMode.Left, ' ');
FieldOffset = offset;
FieldLength = length;

if (align != null)
Expand Down Expand Up @@ -117,7 +124,10 @@ internal override ExtractedInfo ExtractFieldString(LineInfo line)
").You can use the [FixedLengthRecord(FixedMode.AllowMoreChars)] to avoid this problem.");
}
else
{
line.mCurrentPos = line.mCurrentPos + FieldOffset;
return new ExtractedInfo(line, line.mCurrentPos + FieldLength);
}
}

/// <summary>
Expand All @@ -130,6 +140,7 @@ protected override void CreateFieldString(StringBuilder sb, string field, bool i
{
field = GetActualValueBasedOnFieldConfiguration(field);

sb.Append(' ', FieldOffset);
if (Align.Align == AlignMode.Left) {
sb.Append(field);
sb.Append(Align.AlignChar, FieldLength - field.Length);
Expand Down Expand Up @@ -178,6 +189,7 @@ protected override FieldBase CreateClone()
var res = new FixedLengthField {
Align = Align,
FieldLength = FieldLength,
FieldOffset = FieldOffset,
OverflowMode = OverflowMode,
FixedMode = FixedMode
};
Expand All @@ -186,4 +198,4 @@ protected override FieldBase CreateClone()

#endregion
}
}
}