Skip to content

Commit eca6002

Browse files
committed
ParameterParser and various mapping-by-code mappers: When parsing new lines, allow both CRLF and lone LF. Primary reason right now is some tests contain newlines that depend on the build machine EOL convention.
1 parent 135498c commit eca6002

File tree

12 files changed

+113
-16
lines changed

12 files changed

+113
-16
lines changed

src/NHibernate.Test/UtilityTest/StringHelperFixture.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,35 @@ public void PurgeBackticksEnclosing()
137137
Assert.That(StringHelper.PurgeBackticksEnclosing("something`"), Is.EqualTo("something`"));
138138
Assert.That(StringHelper.PurgeBackticksEnclosing("`something`"), Is.EqualTo("something"));
139139
}
140+
141+
142+
[TestCase("ab", 0, -1, 0)]
143+
[TestCase("a\r\nb", 0, 1, 2)]
144+
[TestCase("a\nb", 0, 1, 1)]
145+
[TestCase("ab\r\nfoo\r\n", 4, 7, 2)]
146+
public void IndexOfAnyNewLineReturnsIndexAndLength(string str, int startIndex, int expectedIndex,
147+
int expectedMatchLength)
148+
{
149+
int matchLength;
150+
var matchIndex = str.IndexOfAnyNewLine(startIndex, out matchLength);
151+
152+
Assert.That(matchIndex, Is.EqualTo(expectedIndex));
153+
Assert.That(matchLength, Is.EqualTo(expectedMatchLength));
154+
}
155+
156+
157+
[TestCase("ab", 0, false, 0)]
158+
[TestCase("a\r\nb", 0, false, 0)]
159+
[TestCase("a\nb", 1, true, 1)]
160+
[TestCase("a\r\nb", 1, true, 2)]
161+
public void IsAnyNewLineMatchAndLength(string str, int startIndex, bool expectNewLine,
162+
int expectedMatchLength)
163+
{
164+
int matchLength;
165+
var isNewLine = str.IsAnyNewLine(startIndex, out matchLength);
166+
167+
Assert.That(isNewLine, Is.EqualTo(expectNewLine));
168+
Assert.That(matchLength, Is.EqualTo(expectedMatchLength));
169+
}
140170
}
141171
}

src/NHibernate/Engine/Query/ParameterParser.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace NHibernate.Engine.Query
1212
/// </summary>
1313
public class ParameterParser
1414
{
15-
private static readonly int NewLineLength = Environment.NewLine.Length;
16-
1715
public interface IRecognizer
1816
{
1917
void OutParameter(int position);
@@ -56,6 +54,8 @@ public static void Parse(string sqlString, IRecognizer recognizer)
5654
bool afterNewLine = false;
5755
for (int indx = 0; indx < stringLength; indx++)
5856
{
57+
int currentNewLineLength;
58+
5959
// check comments
6060
if (indx + 1 < stringLength && sqlString.Substring(indx,2) == "/*")
6161
{
@@ -64,9 +64,11 @@ public static void Parse(string sqlString, IRecognizer recognizer)
6464
indx = closeCommentIdx + 1;
6565
continue;
6666
}
67+
6768
if (afterNewLine && (indx + 1 < stringLength) && sqlString.Substring(indx, 2) == "--")
6869
{
69-
var closeCommentIdx = sqlString.IndexOf(Environment.NewLine, indx + 2);
70+
var closeCommentIdx = sqlString.IndexOfAnyNewLine(indx + 2, out currentNewLineLength);
71+
7072
string comment;
7173
if (closeCommentIdx == -1)
7274
{
@@ -75,16 +77,17 @@ public static void Parse(string sqlString, IRecognizer recognizer)
7577
}
7678
else
7779
{
78-
comment = sqlString.Substring(indx, closeCommentIdx - indx + Environment.NewLine.Length);
80+
comment = sqlString.Substring(indx, closeCommentIdx - indx + currentNewLineLength);
7981
}
8082
recognizer.Other(comment);
81-
indx = closeCommentIdx + NewLineLength - 1;
83+
indx = closeCommentIdx + currentNewLineLength - 1;
8284
continue;
8385
}
84-
if (indx + NewLineLength -1 < stringLength && sqlString.Substring(indx, NewLineLength) == Environment.NewLine)
86+
87+
if (sqlString.IsAnyNewLine(indx, out currentNewLineLength))
8588
{
8689
afterNewLine = true;
87-
indx += NewLineLength - 1;
90+
indx += currentNewLineLength - 1;
8891
recognizer.Other(Environment.NewLine);
8992
continue;
9093
}

src/NHibernate/Mapping/ByCode/Impl/DiscriminatorMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using NHibernate.Cfg.MappingSchema;
44
using NHibernate.Type;
5+
using NHibernate.Util;
56

67
namespace NHibernate.Mapping.ByCode.Impl
78
{
@@ -94,7 +95,7 @@ public void Formula(string formula)
9495

9596
ResetColumnPlainValues();
9697
discriminatorMapping.Item = null;
97-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
98+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
9899
if (formulaLines.Length > 1)
99100
{
100101
discriminatorMapping.Item = new HbmFormula {Text = formulaLines};

src/NHibernate/Mapping/ByCode/Impl/ElementMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NHibernate.Cfg.MappingSchema;
55
using NHibernate.Type;
66
using NHibernate.UserTypes;
7+
using NHibernate.Util;
78

89
namespace NHibernate.Mapping.ByCode.Impl
910
{
@@ -192,7 +193,7 @@ public void Formula(string formula)
192193

193194
ResetColumnPlainValues();
194195
elementMapping.Items = null;
195-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
196+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
196197
if (formulaLines.Length > 1)
197198
{
198199
elementMapping.Items = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Mapping/ByCode/Impl/FilterMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using NHibernate.Cfg.MappingSchema;
3+
using NHibernate.Util;
34

45
namespace NHibernate.Mapping.ByCode.Impl
56
{
@@ -35,7 +36,7 @@ public void Condition(string sqlCondition)
3536
filter.Text = null;
3637
return;
3738
}
38-
string[] conditionLines = sqlCondition.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
39+
string[] conditionLines = sqlCondition.Split(StringHelper.LineSeparators, StringSplitOptions.None);
3940
if (conditionLines.Length > 1)
4041
{
4142
filter.Text = conditionLines;

src/NHibernate/Mapping/ByCode/Impl/ManyToManyMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Util;
56

67
namespace NHibernate.Mapping.ByCode.Impl
78
{
@@ -128,7 +129,7 @@ public void Formula(string formula)
128129

129130
ResetColumnPlainValues();
130131
manyToMany.Items = null;
131-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
132+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
132133
if (formulaLines.Length > 1)
133134
{
134135
manyToMany.Items = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Mapping/ByCode/Impl/ManyToOneMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Reflection;
55
using NHibernate.Cfg.MappingSchema;
6+
using NHibernate.Util;
67

78
namespace NHibernate.Mapping.ByCode.Impl
89
{
@@ -82,7 +83,7 @@ public void Formula(string formula)
8283

8384
ResetColumnPlainValues();
8485
_manyToOne.Items = null;
85-
string[] formulaLines = formula.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
86+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
8687
if (formulaLines.Length > 1)
8788
{
8889
_manyToOne.Items = new[] { new HbmFormula { Text = formulaLines } };

src/NHibernate/Mapping/ByCode/Impl/MapKeyManyToManyMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Util;
56

67
namespace NHibernate.Mapping.ByCode.Impl
78
{
@@ -36,7 +37,7 @@ public void Formula(string formula)
3637

3738
ResetColumnPlainValues();
3839
mapping.Items = null;
39-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
40+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
4041
if (formulaLines.Length > 1)
4142
{
4243
mapping.Items = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Mapping/ByCode/Impl/MapKeyMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NHibernate.Cfg.MappingSchema;
55
using NHibernate.Type;
66
using NHibernate.UserTypes;
7+
using NHibernate.Util;
78

89
namespace NHibernate.Mapping.ByCode.Impl
910
{
@@ -112,7 +113,7 @@ public void Formula(string formula)
112113

113114
ResetColumnPlainValues();
114115
hbmMapKey.Items = null;
115-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
116+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
116117
if (formulaLines.Length > 1)
117118
{
118119
hbmMapKey.Items = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Mapping/ByCode/Impl/OneToOneMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq.Expressions;
33
using System.Reflection;
44
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Util;
56

67
namespace NHibernate.Mapping.ByCode.Impl
78
{
@@ -101,7 +102,7 @@ public void Formula(string formula)
101102
return;
102103
}
103104

104-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
105+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
105106
if (formulaLines.Length > 1)
106107
{
107108
_oneToOne.formula = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Mapping/ByCode/Impl/PropertyMapper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using NHibernate.Cfg.MappingSchema;
66
using NHibernate.Type;
77
using NHibernate.UserTypes;
8+
using NHibernate.Util;
89

910
namespace NHibernate.Mapping.ByCode.Impl
1011
{
@@ -231,7 +232,7 @@ public void Formula(string formula)
231232

232233
ResetColumnPlainValues();
233234
propertyMapping.Items = null;
234-
string[] formulaLines = formula.Split(new[] {Environment.NewLine}, StringSplitOptions.None);
235+
string[] formulaLines = formula.Split(StringHelper.LineSeparators, StringSplitOptions.None);
235236
if (formulaLines.Length > 1)
236237
{
237238
propertyMapping.Items = new[] {new HbmFormula {Text = formulaLines}};

src/NHibernate/Util/StringHelper.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
using System.Runtime.CompilerServices;
12
using System;
23
using System.Collections;
34
using System.Collections.Generic;
45
using System.Linq;
56
using System.Text;
67

8+
[assembly: InternalsVisibleTo("NHibernate.Test")]
79

810
namespace NHibernate.Util
911
{
1012
/// <summary></summary>
1113
public static class StringHelper
1214
{
15+
/// <summary>
16+
/// This allows for both CRLF and lone LF line separators.
17+
/// </summary>
18+
internal static readonly string[] LineSeparators = {"\r\n", "\n"};
19+
1320
public const string WhiteSpace = " \n\r\f\t";
1421

1522
/// <summary></summary>
@@ -724,5 +731,53 @@ public static string[] ParseFilterParameterName(string filterParameterName)
724731
string parameterName = filterParameterName.Substring(dot + 1);
725732
return new[] { filterName, parameterName };
726733
}
734+
735+
736+
/// <summary>
737+
/// Return the index of the next line separator, starting at startIndex. If will match
738+
/// the first CRLF or LF line separator. If there is no match, -1 will be returned. When
739+
/// returning, newLineLength will be set to the number of characters in the matched line
740+
/// separator (1 if LF was found, 2 if CRLF was found).
741+
/// </summary>
742+
internal static int IndexOfAnyNewLine(this string str, int startIndex, out int newLineLength)
743+
{
744+
newLineLength = 0;
745+
var matchStartIdx = str.IndexOfAny(new[] {'\r', '\n'}, startIndex);
746+
747+
if (matchStartIdx == -1)
748+
return -1;
749+
750+
if (string.Compare(str, matchStartIdx, "\r\n", 0, 2, StringComparison.OrdinalIgnoreCase) == 0)
751+
newLineLength = 2;
752+
else
753+
newLineLength = 1;
754+
755+
return matchStartIdx;
756+
}
757+
758+
759+
/// <summary>
760+
/// Check if the given index points to a line separator in the string. Both CRLF and LF
761+
/// line separators are handled. When returning, newLineLength will be set to the number
762+
/// of characters matched in the line separator. It will be 2 if a CRLF matched, 1 if LF
763+
/// matched, and 0 if the index doesn't indicate (the start of) a line separator.
764+
/// </summary>
765+
internal static bool IsAnyNewLine(this string str, int index, out int newLineLength)
766+
{
767+
if (string.Compare(str, index, "\r\n", 0, 2, StringComparison.OrdinalIgnoreCase) == 0)
768+
{
769+
newLineLength = 2;
770+
return true;
771+
}
772+
773+
if (index < str.Length && str[index] == '\n')
774+
{
775+
newLineLength = 1;
776+
return true;
777+
}
778+
779+
newLineLength = 0;
780+
return false;
781+
}
727782
}
728783
}

0 commit comments

Comments
 (0)