Skip to content

Commit 83411e2

Browse files
committed
init
1 parent 1cfe94d commit 83411e2

17 files changed

+280
-9
lines changed
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<RootNamespace>Oucc.AotCsv.ConsoleApp</RootNamespace>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\AotCsv\AotCsv.Generator\AotCsv.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
13+
<ProjectReference Include="..\AotCsv\AotCsv\AotCsv.csproj" />
14+
</ItemGroup>
15+
16+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Oucc.AotCsv.Attributes;
2+
3+
namespace Oucc.AotCsv.ConsoleApp.GeneratedCodeTarget;
4+
5+
internal partial class SampleModel
6+
{
7+
[CsvName("ID")]
8+
public int Id { get; set; }
9+
10+
[CsvName("名")]
11+
public required string FirstName { get; init; }
12+
13+
public string? MiddleName { get; private set; }
14+
15+
[CsvName("姓")]
16+
public required string LastName { get; init; }
17+
18+
[CsvIgnore]
19+
public string FullName
20+
{
21+
get => $"{FirstName} {MiddleName} {LastName}";
22+
set
23+
{
24+
var names = value.Split();
25+
if (names is [_, var middle, _])
26+
{
27+
MiddleName = middle;
28+
}
29+
}
30+
}
31+
32+
[CsvDateTimeFormat("yyyy年MM月dd日")]
33+
public DateTime BirthDay { get; set; }
34+
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Oucc.AotCsv.GeneratorHelpers;
2+
3+
namespace Oucc.AotCsv.ConsoleApp.GeneratedCodeTarget;
4+
5+
internal partial class SampleModel : ICsvParsable<SampleModel>
6+
{
7+
static bool ICsvParsable<SampleModel>.TryParse(CsvParser reader, out SampleModel value)
8+
{
9+
throw new NotImplementedException();
10+
}
11+
12+
static bool ICsvParsable<SampleModel>.TryWrite(CsvWriter reader, SampleModel value)
13+
{
14+
throw new NotImplementedException();
15+
}
16+
}

AotCsv.ConsoleApp/Program.cs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Console.WriteLine("Hello, World!");

AotCsv.sln

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AotCsv.Package", "AotCsv\Ao
99
EndProject
1010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AotCsv.Test", "AotCsv\AotCsv.Test\AotCsv.Test.csproj", "{8E7951DD-A2D4-48C4-9EB8-AC0AD6452AF2}"
1111
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AotCsv", "AotCsv\AotCsv\AotCsv.csproj", "{BECBD7AC-595B-4612-BCB1-54840536DD1B}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AotCsv", "AotCsv\AotCsv\AotCsv.csproj", "{BECBD7AC-595B-4612-BCB1-54840536DD1B}"
13+
EndProject
14+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AotCsv.ConsoleApp", "AotCsv.ConsoleApp\AotCsv.ConsoleApp.csproj", "{F8092B51-A23B-4651-9292-DF9F720B0F7A}"
1315
EndProject
1416
Global
1517
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -31,6 +33,10 @@ Global
3133
{BECBD7AC-595B-4612-BCB1-54840536DD1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
3234
{BECBD7AC-595B-4612-BCB1-54840536DD1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
3335
{BECBD7AC-595B-4612-BCB1-54840536DD1B}.Release|Any CPU.Build.0 = Release|Any CPU
36+
{F8092B51-A23B-4651-9292-DF9F720B0F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37+
{F8092B51-A23B-4651-9292-DF9F720B0F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
38+
{F8092B51-A23B-4651-9292-DF9F720B0F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
39+
{F8092B51-A23B-4651-9292-DF9F720B0F7A}.Release|Any CPU.Build.0 = Release|Any CPU
3440
EndGlobalSection
3541
GlobalSection(SolutionProperties) = preSolution
3642
HideSolutionNode = FALSE

AotCsv/AotCsv/AotCsv.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFrameworks>net7.0</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
7-
<RootNamespace>Oucc.AotCsv.Generator</RootNamespace>
7+
<RootNamespace>Oucc.AotCsv</RootNamespace>
88
</PropertyGroup>
99

1010
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace Oucc.AotCsv.Attributes;
4+
5+
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
6+
public sealed class CsvDateTimeFormatAttribute : Attribute
7+
{
8+
public string DateFormat { get; }
9+
10+
public CsvDateTimeFormatAttribute([StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string dateFormat)
11+
{
12+
DateFormat = dateFormat;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace Oucc.AotCsv.Attributes;
2+
3+
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
4+
public sealed class CsvIgnoreAttribute : Attribute { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Oucc.AotCsv.Attributes;
2+
3+
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
4+
public sealed class CsvNameAttribute : Attribute
5+
{
6+
public string Name { get; }
7+
8+
public CsvNameAttribute(string name)
9+
{
10+
Name = name;
11+
}
12+
}

AotCsv/AotCsv/Class1.cs

-7
This file was deleted.

AotCsv/AotCsv/CsvReader.cs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Globalization;
2+
using Oucc.AotCsv.GeneratorHelpers;
3+
4+
namespace Oucc.AotCsv;
5+
6+
public class CsvReader
7+
{
8+
private CsvParser _parser;
9+
public CultureInfo Culture { get; }
10+
11+
public CsvReader(TextReader reader, CultureInfo cultureInfo) : this(new CsvParser(reader, cultureInfo), cultureInfo) { }
12+
13+
private CsvReader(CsvParser parser, CultureInfo culture)
14+
{
15+
_parser = parser;
16+
Culture = culture;
17+
}
18+
19+
public IEnumerable<T> GetRecords<T>() where T : ICsvParsable<T>
20+
{
21+
while (T.TryParse(_parser, out var result))
22+
{
23+
yield return result;
24+
}
25+
}
26+
}

AotCsv/AotCsv/CsvWriter.cs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace Oucc.AotCsv;
2+
3+
public class CsvWriter
4+
{
5+
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System.Buffers;
2+
using System.Globalization;
3+
4+
namespace Oucc.AotCsv.GeneratorHelpers;
5+
6+
public class CsvParser
7+
{
8+
// 131072 byte
9+
private const int ReadBlock = 65536;
10+
private readonly TextReader _reader;
11+
private readonly CultureInfo _culture;
12+
13+
private char[]? _buffer;
14+
private int _bufferOffset;
15+
private int _bufferLength;
16+
17+
internal CsvParser(TextReader reader, CultureInfo culture)
18+
{
19+
_reader = reader;
20+
_culture = culture;
21+
}
22+
23+
public FieldState TryGetLine(out ReadOnlySpan<char> line)
24+
{
25+
Span<char> spanBuffer;
26+
if (_buffer is null)
27+
{
28+
spanBuffer = _buffer = ArrayPool<char>.Shared.Rent(ReadBlock);
29+
_bufferOffset = 0;
30+
_bufferLength = _reader.Read(spanBuffer);
31+
if (_bufferLength == 0)
32+
{
33+
line = default;
34+
return FieldState.NoLine;
35+
}
36+
spanBuffer = spanBuffer[.._bufferLength];
37+
}
38+
else
39+
{
40+
spanBuffer = _buffer.AsSpan()[_bufferOffset.._bufferLength];
41+
}
42+
43+
var endLinePosition = spanBuffer.IndexOfAny('\r', '\n');
44+
var noLine = false;
45+
while (endLinePosition < 0)
46+
{
47+
noLine = !TryRead();
48+
spanBuffer = _buffer.AsSpan()[_bufferOffset.._bufferLength];
49+
endLinePosition = spanBuffer.IndexOfAny('\r', '\n');
50+
}
51+
52+
if (spanBuffer[endLinePosition] == '\r')
53+
{
54+
if (spanBuffer.Length == endLinePosition + 1)
55+
{
56+
noLine = !TryRead();
57+
spanBuffer = _buffer.AsSpan()[_bufferOffset.._bufferLength];
58+
}
59+
60+
if (spanBuffer[endLinePosition + 1] == '\n') _bufferOffset += endLinePosition + 2;
61+
else _bufferOffset += endLinePosition + 1;
62+
}
63+
else _bufferOffset += endLinePosition + 1;
64+
65+
line = spanBuffer[..endLinePosition];
66+
return FieldState.HasField;
67+
}
68+
69+
private bool TryRead()
70+
{
71+
if (_buffer is null)
72+
{
73+
Span<char> spanBuffer = _buffer = ArrayPool<char>.Shared.Rent(ReadBlock);
74+
_bufferOffset = 0;
75+
_bufferLength = _reader.Read(spanBuffer);
76+
77+
return _bufferLength != 0;
78+
}
79+
else
80+
{
81+
Span<char> currentBuffer = _buffer.AsSpan()[_bufferOffset.._bufferLength];
82+
if (currentBuffer.Length < ReadBlock)
83+
{
84+
var nextBuffer = ArrayPool<char>.Shared.Rent(ReadBlock);
85+
var span = nextBuffer.AsSpan();
86+
87+
currentBuffer.CopyTo(span);
88+
var readLength = _reader.Read(span[currentBuffer.Length..]);
89+
_bufferLength = currentBuffer.Length + readLength;
90+
91+
ArrayPool<char>.Shared.Return(_buffer);
92+
_buffer = nextBuffer;
93+
_bufferOffset = 0;
94+
return readLength != 0;
95+
}
96+
else
97+
{
98+
var nextBuffer = ArrayPool<char>.Shared.Rent(currentBuffer.Length + ReadBlock);
99+
var span = nextBuffer.AsSpan();
100+
101+
currentBuffer.CopyTo(span);
102+
var readLength = _reader.Read(span[currentBuffer.Length..]);
103+
_bufferLength = currentBuffer.Length + readLength;
104+
105+
ArrayPool<char>.Shared.Return(_buffer);
106+
_buffer = nextBuffer;
107+
_bufferOffset = 0;
108+
return readLength != 0;
109+
}
110+
}
111+
}
112+
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Oucc.AotCsv.GeneratorHelpers;
2+
3+
public enum FieldState: byte
4+
{
5+
NoLine,
6+
NoField,
7+
HasField
8+
}

AotCsv/AotCsv/ICsvParsable.cs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Oucc.AotCsv.GeneratorHelpers;
2+
3+
namespace Oucc.AotCsv;
4+
5+
public interface ICsvParsable<T> where T : ICsvParsable<T>
6+
{
7+
static abstract bool TryParse(CsvParser reader, out T value);
8+
9+
static abstract bool TryWrite(CsvWriter reader, T value);
10+
}

ConsoleApp/ConsoleApp.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>

ConsoleApp/Program.cs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// See https://aka.ms/new-console-template for more information
2+
Console.WriteLine("Hello, World!");

0 commit comments

Comments
 (0)