Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: PoC implementing Wkt parser using Pidgin Parser Combinator lib #121

Draft
wants to merge 8 commits into
base: develop
Choose a base branch
from
124 changes: 124 additions & 0 deletions ProjNet.IO.Wkt.Tests/Core/WktParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using NUnit.Framework;
using Pidgin;
using ProjNet.IO.Wkt.Core;

namespace ProjNet.IO.Wkt.Tests.Core;

public class WktParserTests
{

[Test]
public void TestUnsignedIntegerParser()
{
// Arrange
string parserText01 = $@"210677";

// Act
uint parserResult01 = WktParser.UnsignedIntegerParser.ParseOrThrow(parserText01);

// Assert
Assert.That(parserResult01, Is.EqualTo(210677));
}

[Test]
public void TestSignedIntegerParser()
{
// Arrange
string parserText01 = $@"+210677";
string parserText02 = $@"-210677";
string parserText03 = $@"210677";

// Act
int parserResult01 = WktParser.SignedIntegerParser.ParseOrThrow(parserText01);
int parserResult02 = WktParser.SignedIntegerParser.ParseOrThrow(parserText02);
int parserResult03 = WktParser.SignedIntegerParser.ParseOrThrow(parserText03);

// Assert
Assert.That(parserResult01, Is.EqualTo(210677));
Assert.That(parserResult02, Is.EqualTo(-210677));
Assert.That(parserResult03, Is.EqualTo(210677));
}


[Test]
public void TestSignedNumericLiteralParser()
{
// Arrange
string parserText01 = "-100.333333333333";
string parserText02 = "+100.333333333333";
string parserText03 = "100.333333333333";
string parserText04 = ".333333333333";

// Act
double parserResult01 = WktParser.SignedNumericLiteralParser.ParseOrThrow(parserText01);
double parserResult02 = WktParser.SignedNumericLiteralParser.ParseOrThrow(parserText02);
double parserResult03 = WktParser.SignedNumericLiteralParser.ParseOrThrow(parserText03);
double parserResult04 = WktParser.SignedNumericLiteralParser.ParseOrThrow(parserText04);

// Assert
Assert.That(parserResult01, Is.EqualTo(-100.333333333333));
Assert.That(parserResult02, Is.EqualTo(100.333333333333));
Assert.That(parserResult03, Is.EqualTo(100.333333333333));
Assert.That(parserResult04, Is.EqualTo(0.333333333333));
}

[Test]
public void TestExactNumericLiteralParser()
{
// Arrange
string parserText01 = $@"21.043";
string parserText02 = $@"0.043";
string parserText03 = $@".043";

// Act
double parserResult01 = WktParser.ExactNumericLiteralParser.ParseOrThrow(parserText01);
double parserResult02 = WktParser.ExactNumericLiteralParser.ParseOrThrow(parserText02);
double parserResult03 = WktParser.ExactNumericLiteralParser.ParseOrThrow(parserText03);

// Assert
Assert.That(parserResult01, Is.EqualTo(21.043d));
Assert.That(parserResult02, Is.EqualTo(0.043d));
Assert.That(parserResult03, Is.EqualTo(0.043d));
}

[Test]
public void TestApproximateNumericLiteralParser()
{
// Arrange
string parserText01 = $@"21.04E-3";
string parserText02= $@"21.04E+3";
string parserText03 = $@"21.04E3";
string parserText04 = $@"0.04E3";
string parserText05 = $@".04E3";

// Act
double parserResult01 = WktParser.ApproximateNumericLiteralParser.ParseOrThrow(parserText01);
double parserResult02 = WktParser.ApproximateNumericLiteralParser.ParseOrThrow(parserText02);
double parserResult03 = WktParser.ApproximateNumericLiteralParser.ParseOrThrow(parserText03);
double parserResult04 = WktParser.ApproximateNumericLiteralParser.ParseOrThrow(parserText04);
double parserResult05 = WktParser.ApproximateNumericLiteralParser.ParseOrThrow(parserText05);

// Assert
Assert.That(parserResult01, Is.EqualTo(0.02104d));
Assert.That(parserResult02, Is.EqualTo(21040d));
Assert.That(parserResult03, Is.EqualTo(21040d));
Assert.That(parserResult04, Is.EqualTo(40d));
Assert.That(parserResult05, Is.EqualTo(40d));
}

[Test]
public void TestQuotedNameParser()
{
// Arrange
string str01 = "MyTextString";
string parserText01 = $"\"{str01}\"";

// Act
string parserResult01 = WktParser.QuotedNameParser.ParseOrThrow(parserText01);

// Assert
Assert.That(parserResult01, Is.EqualTo(str01));
}


}
12 changes: 12 additions & 0 deletions ProjNet4GeoAPI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjNET.Tests", "test\ProjN
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjNet.Benchmark", "src\ProjNet.Benchmark\ProjNet.Benchmark.csproj", "{1E5D1CC5-8CFE-4C9D-9553-900469C57D6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjNet.IO.Wkt", "src\ProjNet.IO.Wkt\ProjNet.IO.Wkt.csproj", "{50AAB59B-25FB-4E36-A31A-B22C62B2105E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjNet.IO.Wkt.Tests", "ProjNet.IO.Wkt.Tests\ProjNet.IO.Wkt.Tests.csproj", "{3E23D15C-56F1-4431-B241-FC17D2F54BBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -33,6 +37,14 @@ Global
{1E5D1CC5-8CFE-4C9D-9553-900469C57D6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E5D1CC5-8CFE-4C9D-9553-900469C57D6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E5D1CC5-8CFE-4C9D-9553-900469C57D6C}.Release|Any CPU.Build.0 = Release|Any CPU
{50AAB59B-25FB-4E36-A31A-B22C62B2105E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{50AAB59B-25FB-4E36-A31A-B22C62B2105E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{50AAB59B-25FB-4E36-A31A-B22C62B2105E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{50AAB59B-25FB-4E36-A31A-B22C62B2105E}.Release|Any CPU.Build.0 = Release|Any CPU
{3E23D15C-56F1-4431-B241-FC17D2F54BBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E23D15C-56F1-4431-B241-FC17D2F54BBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E23D15C-56F1-4431-B241-FC17D2F54BBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E23D15C-56F1-4431-B241-FC17D2F54BBF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 3 additions & 0 deletions src/ProjNet.IO.Wkt/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("ProjNet.IO.Wkt.Tests")]
198 changes: 198 additions & 0 deletions src/ProjNet.IO.Wkt/Core/DefaultWktOutputFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
using System;
using System.Globalization;
using System.Text;

namespace ProjNet.IO.Wkt.Core
{
/// <summary>
/// DefaultWktOutputFormatter - Keeping output compact with original delimiters.
/// </summary>
public class DefaultWktOutputFormatter : IWktOutputFormatter
{
private int indentCounter = 0;

/// <inheritdoc/>
public string Newline { get; } = null;
/// <inheritdoc/>
public char? LeftDelimiter { get; } = null;
/// <inheritdoc/>
public char? RightDelimiter { get; } = null;

/// <inheritdoc/>
public string Separator { get; } = null;

/// <summary>
/// Indent chars. E.g. tab or spaces. Default null.
/// </summary>
public string Indent { get; } = null;

/// <inheritdoc/>
public string ExtraWhitespace { get; } = null;


/// <summary>
/// Constructor with support for optional overriding the settings.
/// </summary>
/// <param name="newline"></param>
/// <param name="leftDelimiter"></param>
/// <param name="rightDelimiter"></param>
/// <param name="indent"></param>
/// <param name="extraWhitespace"></param>
public DefaultWktOutputFormatter(
string newline = null,
char? leftDelimiter = null,
char? rightDelimiter = null,
string indent = null,
string extraWhitespace = null)
{
Newline = newline;
LeftDelimiter = leftDelimiter;
RightDelimiter = rightDelimiter;
Indent = indent;
ExtraWhitespace = extraWhitespace;
}


/// <inheritdoc/>
public IWktOutputFormatter AppendKeyword(string text, StringBuilder result, bool indent = true)
{
if (indent)
this.AppendIndent(result);

result.Append(text);

this.IncreaseIndentCounter();

return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendSeparator(StringBuilder result, bool keepInside = false)
{
string s = Separator ?? ",";
result.Append(s);
if (!keepInside)
{
this.AppendNewline(result);
}

return this;
}


/// <inheritdoc/>
public IWktOutputFormatter Append(string text, StringBuilder result)
{
result.Append(text);
return this;
}

/// <inheritdoc/>
public IWktOutputFormatter Append(long l, StringBuilder result)
{
result.Append(l);
return this;
}

/// <inheritdoc/>
public IWktOutputFormatter Append(double d, StringBuilder result)
{
result.Append(d.ToString(CultureInfo.InvariantCulture));
return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendNewline(StringBuilder result)
{
if (!string.IsNullOrEmpty(Newline))
{
result.Append(Newline);
}

return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendQuotedText(string text, StringBuilder result)
{
result.Append($"\"{text}\"");
return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendLeftDelimiter(char original, StringBuilder result)
{
if (LeftDelimiter != null)
result.Append(LeftDelimiter);
else
result.Append(original);
return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendRightDelimiter(char original, StringBuilder result)
{
//this.AppendIndent(result);

if (RightDelimiter != null)
result.Append(RightDelimiter);
else
result.Append(original);

this.DecreaseIndentCounter();
//this.AppendNewline(result);

return this;
}

/// <inheritdoc/>
public IWktOutputFormatter AppendExtraWhitespace(StringBuilder result)
{
if (!string.IsNullOrEmpty(ExtraWhitespace))
{
result.Append(ExtraWhitespace);
}

return this;
}

/// <summary>
/// Increasing the indentCounter.
/// </summary>
/// <returns></returns>
public IWktOutputFormatter IncreaseIndentCounter()
{
indentCounter++;
return this;
}

/// <summary>
/// Decreasing the indentCounter.
/// </summary>
/// <returns></returns>
public IWktOutputFormatter DecreaseIndentCounter()
{
indentCounter--;
return this;
}


/// <summary>
/// AppendIndent repeat Indent according to internal indentCounter.
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public IWktOutputFormatter AppendIndent(StringBuilder result)
{
if (!string.IsNullOrEmpty(Indent))
{
for (int i = 1; i <= indentCounter; i++)
{
result.Append(Indent);
}
}

return this;
}
}
}
Loading
Loading