-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathHelpers.cs
More file actions
101 lines (87 loc) · 3.05 KB
/
Copy pathHelpers.cs
File metadata and controls
101 lines (87 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#nullable enable
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using ExcelDataReader.Misc;
namespace ExcelDataReader.Core;
/// <summary>
/// Helpers class.
/// </summary>
internal static partial class Helpers
{
#if !NET8_0_OR_GREATER
private static readonly Regex EscapeRegexInstance = new("_x([0-9A-F]{4,4})_", RegexOptions.Compiled);
#endif
private static readonly char[] SingleByteEncodingHelper = ['a'];
/// <summary>
/// Determines whether the encoding is single byte or not.
/// </summary>
/// <param name="encoding">The encoding.</param>
/// <returns>
/// <see langword="true"/> if the specified encoding is single byte; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsSingleByteEncoding(Encoding encoding)
{
return encoding.GetByteCount(SingleByteEncodingHelper) == 1;
}
public static string ConvertEscapeChars(string input)
{
// Fast rejection: the escape pattern always starts with "_x". For typical
// spreadsheet strings this short-circuits before the regex engine is entered.
if (input.IndexOf("_x", StringComparison.Ordinal) < 0)
return input;
return EscapeRegex().Replace(input, m => ((char)uint.Parse(m.Groups[1].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture)).ToString());
}
public static object ConvertFromOATime(double value, bool date1904)
{
var dateValue = AdjustOADateTime(value, date1904);
if (IsValidOADateTime(dateValue))
return DateTimeHelper.FromOADate(dateValue);
return value;
}
public static object ConvertFromOATime(int value, bool date1904)
{
var dateValue = AdjustOADateTime(value, date1904);
if (IsValidOADateTime(dateValue))
return DateTimeHelper.FromOADate(dateValue);
return value;
}
public static bool StringStartsWith(string value, char start)
{
#if NETSTANDARD2_1_OR_GREATER || NET8_0_OR_GREATER
return value.StartsWith(start);
#else
return value.Length > 0 && value[0] == start;
#endif
}
/// <summary>
/// Convert a double from Excel to an OA DateTime double.
/// The returned value is normalized to the '1900' date mode and adjusted for the 1900 leap year bug.
/// </summary>
private static double AdjustOADateTime(double value, bool date1904)
{
if (!date1904)
{
// Workaround for 1900 leap year bug in Excel
if (value is >= 0.0 and < 60.0)
{
return value + 1;
}
}
else
{
return value + 1462.0;
}
return value;
}
private static bool IsValidOADateTime(double value)
{
return value is > DateTimeHelper.OADateMinAsDouble and < DateTimeHelper.OADateMaxAsDouble;
}
#if NET8_0_OR_GREATER
[GeneratedRegex("_x([0-9A-F]{4,4})_")]
private static partial Regex EscapeRegex();
#else
private static Regex EscapeRegex() => EscapeRegexInstance;
#endif
}