Skip to content

Commit 8386d4c

Browse files
authored
Support numbers with exponent in WKT (#3922)
This commit provides support for numbers with an exponent when reading WKT. Fixes #3920
1 parent 90c2bf7 commit 8386d4c

File tree

2 files changed

+27
-43
lines changed

2 files changed

+27
-43
lines changed

src/Nest/QueryDsl/Geo/WKT/GeoWKTReader.cs

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,14 @@ private static TokenType NextCloserOrComma(WellKnownTextTokenizer tokenizer)
259259

260260
private static double NextNumber(WellKnownTextTokenizer tokenizer)
261261
{
262-
if (tokenizer.NextToken() == TokenType.Number)
262+
if (tokenizer.NextToken() == TokenType.Word)
263263
{
264264
if (string.Equals(tokenizer.TokenValue, WellKnownTextTokenizer.NaN, StringComparison.OrdinalIgnoreCase))
265265
return double.NaN;
266266

267267
if (double.TryParse(
268268
tokenizer.TokenValue,
269-
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
269+
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent,
270270
CultureInfo.InvariantCulture, out var d))
271271
return d;
272272
}
@@ -278,7 +278,7 @@ private static double NextNumber(WellKnownTextTokenizer tokenizer)
278278
private static bool IsNumberNext(WellKnownTextTokenizer tokenizer)
279279
{
280280
var token = tokenizer.PeekToken();
281-
return token == TokenType.Number;
281+
return token == TokenType.Word;
282282
}
283283
}
284284

@@ -288,7 +288,6 @@ private static bool IsNumberNext(WellKnownTextTokenizer tokenizer)
288288
internal enum CharacterType : byte
289289
{
290290
Whitespace,
291-
Digit,
292291
Alpha,
293292
Comment
294293
}
@@ -300,7 +299,6 @@ internal enum TokenType : byte
300299
{
301300
None,
302301
Word,
303-
Number,
304302
LParen,
305303
RParen,
306304
Comma
@@ -339,15 +337,14 @@ static WellKnownTextTokenizer()
339337
// build a map of ASCII chars and their types
340338
// Any unmapped ASCII will be considered whitespace
341339
// and anything > 0 outside of ASCII will be considered alpha.
342-
// Treat + - and . as digit characters to make parsing numbers easier.
343340
Chars('a', 'z', CharacterType.Alpha);
344341
Chars('A', 'Z', CharacterType.Alpha);
345342
Chars(128 + 32, 255, CharacterType.Alpha);
346-
Chars('0', '9', CharacterType.Digit);
343+
Chars('0', '9', CharacterType.Alpha);
347344
Chars(LParen, RParen, CharacterType.Alpha);
348-
Chars(Plus, Plus, CharacterType.Digit);
345+
Chars(Plus, Plus, CharacterType.Alpha);
349346
Chars(Comma, Comma, CharacterType.Alpha);
350-
Chars(Minus, Dot, CharacterType.Digit);
347+
Chars(Minus, Dot, CharacterType.Alpha);
351348
Chars(Comment, Comment, CharacterType.Comment);
352349
}
353350

@@ -399,7 +396,6 @@ public string TokenString()
399396
switch (TokenType)
400397
{
401398
case TokenType.Word:
402-
case TokenType.Number:
403399
return TokenValue;
404400
case TokenType.None:
405401
return "END-OF-STREAM";
@@ -514,33 +510,6 @@ public TokenType NextToken()
514510
{
515511
var i = 0;
516512

517-
do
518-
{
519-
_buffer.Insert(i++, (char)c);
520-
c = Read();
521-
522-
if (c < 0)
523-
characterType = CharacterType.Whitespace;
524-
else if (c < CharacterTypesLength)
525-
characterType = CharacterTypes[c];
526-
else
527-
characterType = CharacterType.Alpha;
528-
} while (characterType == CharacterType.Alpha);
529-
530-
_peekChar = c;
531-
TokenValue = new string(_buffer.ToArray(), 0, i);
532-
533-
// special case for NaN
534-
if (string.Equals(TokenValue, NaN, StringComparison.OrdinalIgnoreCase))
535-
return TokenType = TokenType.Number;
536-
537-
return TokenType = TokenType.Word;
538-
}
539-
540-
if (characterType == CharacterType.Digit)
541-
{
542-
var i = 0;
543-
var dots = 0;
544513
do
545514
{
546515
_buffer.Insert(i++, (char)c);
@@ -550,20 +519,19 @@ public TokenType NextToken()
550519
characterType = CharacterType.Whitespace;
551520
else if (c < CharacterTypesLength)
552521
{
522+
if (c == LParen || c == RParen || c == Comma)
523+
break;
524+
553525
characterType = CharacterTypes[c];
554-
if (c == Dot)
555-
dots++;
556526
}
557527
else
558528
characterType = CharacterType.Alpha;
559-
} while (characterType == CharacterType.Digit);
529+
} while (characterType == CharacterType.Alpha);
560530

561531
_peekChar = c;
562532
TokenValue = new string(_buffer.ToArray(), 0, i);
563533

564-
return dots > 1
565-
? TokenType = TokenType.Word
566-
: TokenType = TokenType.Number;
534+
return TokenType = TokenType.Word;
567535
}
568536

569537
if (characterType == CharacterType.Comment)

src/Tests/Tests/QueryDsl/Geo/Shape/GeoWKTTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ public void ReadAndWritePoint()
2323
GeoWKTWriter.Write(point).Should().Be(wkt);
2424
}
2525

26+
[U]
27+
public void ReadAndWritePointWithExponent()
28+
{
29+
var wkt = "POINT (1.2E2 -2.5E-05)";
30+
var shape = GeoWKTReader.Read(wkt);
31+
32+
shape.Should().BeOfType<PointGeoShape>();
33+
var point = (PointGeoShape)shape;
34+
35+
point.Coordinates.Latitude.Should().Be(-0.000025);
36+
point.Coordinates.Longitude.Should().Be(120);
37+
38+
// 1.2E2 will be expanded
39+
GeoWKTWriter.Write(point).Should().Be("POINT (120 -2.5E-05)");
40+
}
41+
2642
[U]
2743
public void ReadAndWriteMultiPoint()
2844
{

0 commit comments

Comments
 (0)