Skip to content
Merged
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
28 changes: 27 additions & 1 deletion Px.Utils.UnitTests/PxFileTests/DataTests/DataValueParserTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Px.Utils.Models.Data;
using Px.Utils.Models.Data;
using Px.Utils.Models.Data.DataValue;
using Px.Utils.PxFile.Data;

Expand Down Expand Up @@ -317,6 +317,19 @@ public void FastParseDoubleDataValueDangerousEmptySymbolWithoutDelimetersReturns
Assert.AreEqual(DataValueType.Empty, result.Type);
}

[TestMethod]
public void FastParseDoubleDataValueDangerousExcessivelyLongNumberReturnsExistsValueTypeWithCorrectUnsafeValue()
{
// Arrange (1.91287503458359810)
char[] buffer = ['1', '.', '9', '1', '2', '8', '7', '5', '0', '3', '4', '5', '8', '3', '5', '9', '8', '1', '0']; // 19 characters
int len = buffer.Length;
// Act
DoubleDataValue result = DataValueParsers.FastParseDoubleDataValueDangerous(buffer, len);
// Assert
Assert.AreEqual(DataValueType.Exists, result.Type);
Assert.AreEqual(1.9128750345835981, result.UnsafeValue);
}

#endregion

#region FastParseDecimalDataValueDangerous
Expand Down Expand Up @@ -629,6 +642,19 @@ public void FastParseDecimalDataValueDangerousEmptySymbolWithoutDelimetersReturn
Assert.AreEqual(DataValueType.Empty, result.Type);
}

[TestMethod]
public void FastParseDecimalDataValueDangerousExcessivelyLongNumberReturnsExistsValueTypeWithCorrectUnsafeValue()
{
// Arrange (1.91287503458359810)
char[] buffer = ['1', '.', '9', '1', '2', '8', '7', '5', '0', '3', '4', '5', '8', '3', '5', '9', '8', '1', '0']; // 19 characters
int len = buffer.Length;
// Act
DecimalDataValue result = DataValueParsers.FastParseDecimalDataValueDangerous(buffer, len);
// Assert
Assert.AreEqual(DataValueType.Exists, result.Type);
Assert.AreEqual(1.91287503458359810m, result.UnsafeValue);
}

#endregion

#region FastParseUnsafeDoubleDangerous
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Px.Utils.Models.Metadata;
using Px.Utils.Models.Metadata;
using Px.Utils.PxFile.Data;
using Px.Utils.UnitTests;
using PxFileTests.Fixtures;
Expand Down Expand Up @@ -319,7 +319,7 @@ public void EveryValueOnSeparateRowsValidDecimalsReturnsCorrectDoubleDataValues(
0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19
];

CollectionAssert.AreEqual( expexted, targetBuffer.Select(v => v.UnsafeValue).ToArray());
CollectionAssert.AreEqual(expexted, targetBuffer.Select(v => v.UnsafeValue).ToArray());
}

[TestMethod]
Expand Down Expand Up @@ -481,5 +481,59 @@ public void ReadDoubleDataDimensionsInWrongOrderThrowsArgumentException()
// Assert
Assert.ThrowsException<ArgumentException>(() => reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap));
}
}

[TestMethod]
public void ReadDoubleDataValuesWithExcessivePrecisionReturnsCorrectDoubleDataValues()
{
// Arrange
byte[] data = Encoding.UTF8.GetBytes(DataReaderFixtures.MINIMAL_UTF8__EXCESSIVELYLONGDATAVALUES);
using Stream stream = new MemoryStream(data);
using PxFileStreamDataReader reader = new(stream);
DoubleDataValue[] targetBuffer = new DoubleDataValue[20];

// Act
MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]);
MatrixMap matrixMap = new(
[
new DimensionMap("var0", ["var0_val0", "var0_val1"]),
new DimensionMap("var1", ["var1_val0", "var1_val1"]),
new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"])
]);
reader.ReadDoubleDataValues(targetBuffer, 0, testMeta, matrixMap);

// Assert
double[] expexted =
[
0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9128750345835981
];
CollectionAssert.AreEqual(expexted, targetBuffer.Select(v => v.UnsafeValue).ToArray());
}

[TestMethod]
public void ReadDecimalDataValuesWithExcessivePrecisionReturnsCorrectDecimalDataValues()
{
// Arrange
byte[] data = Encoding.UTF8.GetBytes(DataReaderFixtures.MINIMAL_UTF8__EXCESSIVELYLONGDATAVALUES);
using Stream stream = new MemoryStream(data);
using PxFileStreamDataReader reader = new(stream);
DecimalDataValue[] targetBuffer = new DecimalDataValue[20];
// Act
MatrixMetadata testMeta = TestModelBuilder.BuildTestMetadata([2, 2, 5]);
MatrixMap matrixMap = new(
[
new DimensionMap("var0", ["var0_val0", "var0_val1"]),
new DimensionMap("var1", ["var1_val0", "var1_val1"]),
new DimensionMap("var2", ["var2_val0", "var2_val1", "var2_val2", "var2_val3", "var2_val4"])
]);
reader.ReadDecimalDataValues(targetBuffer, 0, testMeta, matrixMap);
// Assert
decimal[] expexted =
[
0.0m, 0.1m, 0.2m, 0.3m, 0.4m, 0.5m, 0.6m, 0.7m, 0.8m, 0.9m,
1.0m, 1.1m, 1.2m, 1.3m, 1.4m, 1.5m, 1.6m, 1.7m, 1.8m, 1.9128750345835981m
];
CollectionAssert.AreEqual(expexted, targetBuffer.Select(v => v.UnsafeValue).ToArray());
}
}
}
19 changes: 17 additions & 2 deletions Px.Utils.UnitTests/PxFileTests/Fixtures/DataReaderFixtures.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace PxFileTests.Fixtures
namespace PxFileTests.Fixtures
{
internal static class DataReaderFixtures
{
Expand Down Expand Up @@ -76,5 +76,20 @@ 0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09
0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09
0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19;
"""; // observe the trailing space
}

internal static string MINIMAL_UTF8__EXCESSIVELYLONGDATAVALUES =
"""
CHARSET=""Unicode"";
AXIS-VERSION=""2013"";
CODEPAGE=""utf-8"";
LANGUAGES=""aa"",""åå"",""öö"";
NEXT-UPDATE=""20240131 08:00"";
SUBJECT-AREA=""test"";
SUBJECT-AREA[åå]=""test"";
COPYRIGHT=YES;
DATA=
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.91287503458359810;
"""; // Last value has more than 15 characters and differs from one decimal point precision of other values
}
}
39 changes: 30 additions & 9 deletions Px.Utils/PxFile/Data/DataValueParsers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Px.Utils.Models.Data;
using Px.Utils.Models.Data;
using Px.Utils.Models.Data.DataValue;
using System.Globalization;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -264,10 +264,20 @@ private static int CountDots(char[] buffer, int offset, int end)
private static readonly double[] doublePowersOf10 =
[
1d, 1d, 10d, 100d, 1000d,
10000d, 100000d, 1000000d, 10000000d,
100000000d, 1000000000d, 1000000000d, 1000000000d,
10000000000d, 100000000000d, 1000000000000d, 10000000000000d,
100000000000000d, 1000000000000000d
10000d,
100000d,
1000000d,
10000000d,
100000000d,
1000000000d,
10000000000d,
100000000000d,
1000000000000d,
10000000000000d,
100000000000000d,
1000000000000000d,
10000000000000000d,
100000000000000000d
];

/// <summary>
Expand Down Expand Up @@ -303,10 +313,21 @@ private static double FastParseDoubleDangerous(char[] buffer, int len)
private static readonly decimal[] decimalPowersOf10 =
[
1m, 1m, 10m, 100m, 1000m,
10000m, 100000m, 1000000m, 10000000m,
100000000m, 1000000000m, 1000000000m, 1000000000m,
10000000000m, 100000000000m, 1000000000000m, 10000000000000m,
100000000000000m, 1000000000000000m
10000m,
100000m,
1000000m,
10000000m,
100000000m,
1000000000m,
10000000000m,
100000000000m,
1000000000000m,
10000000000000m,
100000000000000m,
1000000000000000m,
10000000000000000m,
100000000000000000m,
1000000000000000000m
];

/// <summary>
Expand Down