diff --git a/FileHelpers.Tests/Tests/Helpers/StringHelperTest.cs b/FileHelpers.Tests/Tests/Helpers/StringHelperTest.cs index d1dbfad32..f00110fcb 100644 --- a/FileHelpers.Tests/Tests/Helpers/StringHelperTest.cs +++ b/FileHelpers.Tests/Tests/Helpers/StringHelperTest.cs @@ -33,6 +33,15 @@ public void RemoveBlanksAfterSign() public void RemoveTrailingBlanks() { StringHelper.RemoveBlanks(" + 41").AssertEqualTo("+41"); + } + + [Test (Description = "String IsNullOrWhiteSpace help method tests")] + public void IsNullOrWhiteSpace () + { + StringHelper.IsNullOrWhiteSpace (" ").AssertEqualTo (true, "WhiteSpaces not detected"); + StringHelper.IsNullOrWhiteSpace (null).AssertEqualTo (true, "null string not detected"); + StringHelper.IsNullOrWhiteSpace (String.Empty).AssertEqualTo (true, "empty string not detected"); + StringHelper.IsNullOrWhiteSpace (" test ").AssertEqualTo (false, "valid string not detected"); } } } diff --git a/FileHelpers/Converters/ConvertHelpers.cs b/FileHelpers/Converters/ConvertHelpers.cs index b009b7ecf..dc45fbd04 100644 --- a/FileHelpers/Converters/ConvertHelpers.cs +++ b/FileHelpers/Converters/ConvertHelpers.cs @@ -622,7 +622,7 @@ protected override object ParseString(string from) { double res; var blanksRemoved = StringHelper.RemoveBlanks(from); - if (blanksRemoved.EndsWith("%")) + if (blanksRemoved.EndsWith ("%", StringComparison.Ordinal)) { if (!Double.TryParse(blanksRemoved, NumberStyles.Number | NumberStyles.AllowExponent, mCulture, out res)) throw new ConvertException(from, mType); @@ -862,8 +862,8 @@ public BooleanConverter(string trueStr, string falseStr) { mTrueString = trueStr; mFalseString = falseStr; - mTrueStringLower = trueStr.ToLower(); - mFalseStringLower = falseStr.ToLower(); + mTrueStringLower = trueStr.ToLowerInvariant (); + mFalseStringLower = falseStr.ToLowerInvariant (); } /// @@ -874,7 +874,7 @@ public BooleanConverter(string trueStr, string falseStr) public override object StringToField(string from) { object val; - string testTo = from.ToLower(); + string testTo = from.ToLowerInvariant (); if (mTrueString == null) { diff --git a/FileHelpers/Core/RecordInfo.cs b/FileHelpers/Core/RecordInfo.cs index ad15c3d77..e7e8ff0cd 100644 --- a/FileHelpers/Core/RecordInfo.cs +++ b/FileHelpers/Core/RecordInfo.cs @@ -345,7 +345,7 @@ private static void CheckForOptionalAndArrayProblems(List resFields) /// List of fields to use private static void SortFieldsByOrder(List resFields) { - if (resFields.FindAll(x => x.FieldOrder.HasValue).Count > 0) + if (resFields.Exists(x => x.FieldOrder.HasValue)) resFields.Sort( (x,y) => x.FieldOrder.Value.CompareTo(y.FieldOrder.Value)); } @@ -378,8 +378,8 @@ private static void CheckForOrderProblems(FieldBase currentField, List x.FieldOrder.HasValue).Count; - if (othersWithOrder > 0) + var othersWithOrder = resFields.Exists (x => x.FieldOrder.HasValue); + if (othersWithOrder) throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(currentField.FieldInfo.Name) .Text); @@ -401,7 +401,7 @@ public int GetFieldIndex(string fieldName) { if (mMapFieldIndex == null) { - mMapFieldIndex = new Dictionary(FieldCount); + mMapFieldIndex = new Dictionary(FieldCount, StringComparer.Ordinal); for (int i = 0; i < FieldCount; i++) { mMapFieldIndex.Add(Fields[i].FieldInfo.Name, i); diff --git a/FileHelpers/Core/RecordOperations.cs b/FileHelpers/Core/RecordOperations.cs index 0af09213a..b2c6f6f13 100644 --- a/FileHelpers/Core/RecordOperations.cs +++ b/FileHelpers/Core/RecordOperations.cs @@ -10,9 +10,13 @@ namespace FileHelpers /// /// Collection of operations that we perform on a type, cached for reuse /// - internal sealed class RecordOperations + internal sealed class RecordOperations //: IRecordOperations { + // internal buffer for RecordToString and RecordValuesToString operations + // this buffer will be released when this instance goes out of scope + StringBuilder mBuffer = null; + /// /// Record Info we use to parse the record and generate an object instance /// @@ -27,7 +31,7 @@ public RecordOperations(IRecordInfo recordInfo) RecordInfo = recordInfo; } - #region " StringToRecord " + #region " StringToRecord " /// /// Process a line and turn it into an object @@ -128,13 +132,13 @@ public bool StringToRecord(object record, LineInfo line, object[] values) private bool MustIgnoreLine(string line) { if (RecordInfo.IgnoreEmptyLines) - if ((RecordInfo.IgnoreEmptySpaces && line.TrimStart().Length == 0) || + if ((RecordInfo.IgnoreEmptySpaces && StringHelper.IsNullOrWhiteSpace (line)) || line.Length == 0) return true; if (!String.IsNullOrEmpty(RecordInfo.CommentMarker)) - if ((RecordInfo.CommentAnyPlace && line.TrimStart().StartsWith(RecordInfo.CommentMarker)) || - line.StartsWith(RecordInfo.CommentMarker)) + if ((RecordInfo.CommentAnyPlace && line.TrimStart ().StartsWith (RecordInfo.CommentMarker, StringComparison.Ordinal)) || + line.StartsWith (RecordInfo.CommentMarker, StringComparison.Ordinal)) return true; if (RecordInfo.RecordCondition != RecordCondition.None) @@ -182,16 +186,21 @@ private bool MustIgnoreLine(string line) /// String representing the object public string RecordToString(object record) { - var sb = new StringBuilder(RecordInfo.SizeHint); + // create or clear internal string buffer + if (mBuffer == null) + mBuffer = new StringBuilder (RecordInfo.SizeHint); + else + mBuffer.Length = 0; + // parse each field var values = ObjectToValuesHandler(record); - + var fields = RecordInfo.Fields; for (int f = 0; f < RecordInfo.FieldCount; f++) { - RecordInfo.Fields[f].AssignToString(sb, values[f]); + fields[f].AssignToString (mBuffer, values[f]); } - return sb.ToString(); + return mBuffer.ToString (); } /// @@ -201,14 +210,20 @@ public string RecordToString(object record) /// String representing values public string RecordValuesToString(object[] recordValues) { - var sb = new StringBuilder(RecordInfo.SizeHint); + // create or clear internal string buffer + if (mBuffer == null) + mBuffer = new StringBuilder (RecordInfo.SizeHint); + else + mBuffer.Length = 0; + // parse each field + var fields = RecordInfo.Fields; for (int f = 0; f < RecordInfo.FieldCount; f++) { - RecordInfo.Fields[f].AssignToString(sb, recordValues[f]); + fields[f].AssignToString (mBuffer, recordValues[f]); } - return sb.ToString(); + return mBuffer.ToString (); } #endregion diff --git a/FileHelpers/Dynamic/ClassBuilder.cs b/FileHelpers/Dynamic/ClassBuilder.cs index 8a80296ea..c77511ac5 100644 --- a/FileHelpers/Dynamic/ClassBuilder.cs +++ b/FileHelpers/Dynamic/ClassBuilder.cs @@ -108,13 +108,13 @@ public static Type ClassFromString(string classStr, string className, NetLanguag case NetLanguage.VbNet: - if (CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports System", CompareOptions.IgnoreCase) == -1) + if (CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports System", CompareOptions.OrdinalIgnoreCase) == -1) code.Append("Imports System\n"); - if (CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports FileHelpers", CompareOptions.IgnoreCase) == -1) + if (CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports FileHelpers", CompareOptions.OrdinalIgnoreCase) == -1) code.Append("Imports FileHelpers\n"); - if (mustAddSystemData && CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports System.Data", CompareOptions.IgnoreCase) == -1) + if (mustAddSystemData && CultureInfo.CurrentCulture.CompareInfo.IndexOf(classStr, "Imports System.Data", CompareOptions.OrdinalIgnoreCase) == -1) code.Append("Imports System.Data\n"); break; @@ -123,7 +123,7 @@ public static Type ClassFromString(string classStr, string className, NetLanguag code.Append(classStr); CodeDomProvider prov = null; - + switch (lang) { case NetLanguage.CSharp: @@ -157,7 +157,7 @@ public static Type ClassFromString(string classStr, string className, NetLanguag if (ts.Length > 0) foreach (var t in ts) { - if (t.FullName.StartsWith("My.My") == false && t.IsDefined(typeof(TypedRecordAttribute), false)) + if (t.FullName.StartsWith ("My.My", StringComparison.Ordinal) == false && t.IsDefined (typeof (TypedRecordAttribute), false)) return t; } @@ -620,7 +620,7 @@ private void AddAttributesInternal(AttributesBuilder attbs) attbs.AddAttribute("ConditionalRecord(RecordCondition." + mRecordConditionInfo.Condition.ToString() + ", \"" + mRecordConditionInfo.Selector + "\")"); if (!string.IsNullOrEmpty(mIgnoreCommentInfo.CommentMarker)) - attbs.AddAttribute("IgnoreCommentedLines(\"" + mIgnoreCommentInfo.CommentMarker + "\", " + mIgnoreCommentInfo.InAnyPlace.ToString().ToLower() + ")"); + attbs.AddAttribute("IgnoreCommentedLines(\"" + mIgnoreCommentInfo.CommentMarker + "\", " + mIgnoreCommentInfo.InAnyPlace.ToString().ToLowerInvariant() + ")"); } @@ -897,7 +897,7 @@ public static ClassBuilder LoadFromXml(XmlDocument document) if (node != null) res.IgnoreCommentedLines.CommentMarker = node.InnerText; node = document.DocumentElement["CommentInAnyPlace"]; - if (node != null) res.IgnoreCommentedLines.InAnyPlace = bool.Parse(node.InnerText.ToLower()); + if (node != null) res.IgnoreCommentedLines.InAnyPlace = bool.Parse(node.InnerText.ToLowerInvariant()); node = document.DocumentElement["SealedClass"]; res.SealedClass = node != null; @@ -1021,7 +1021,7 @@ public void SaveToXml(TextWriter writer) xml.WriteElement("IgnoreLastLines", this.IgnoreLastLines.ToString(), "0"); xml.WriteElement("CommentMarker", this.IgnoreCommentedLines.CommentMarker, string.Empty); - xml.WriteElement("CommentInAnyPlace", this.IgnoreCommentedLines.InAnyPlace.ToString().ToLower(), true.ToString().ToLower()); + xml.WriteElement("CommentInAnyPlace", this.IgnoreCommentedLines.InAnyPlace.ToString().ToLowerInvariant(), true.ToString().ToLowerInvariant()); xml.WriteElement("RecordCondition", this.RecordCondition.Condition.ToString(), "None"); xml.WriteElement("RecordConditionSelector", this.RecordCondition.Selector, string.Empty); diff --git a/FileHelpers/Engines/FileHelperAsyncEngine.cs b/FileHelpers/Engines/FileHelperAsyncEngine.cs index 781806f28..12b66ef88 100644 --- a/FileHelpers/Engines/FileHelperAsyncEngine.cs +++ b/FileHelpers/Engines/FileHelperAsyncEngine.cs @@ -85,6 +85,16 @@ protected FileHelperAsyncEngine(Type recordType, Encoding encoding) [DebuggerBrowsable(DebuggerBrowsableState.Never)] TextWriter mAsyncWriter; + public bool mEof = false; + /// + /// Indicates if End of File was reached. + /// + /// The EOF flag. + public bool Eof + { + get { return mEof; } + } + #endregion #region " LastRecord " @@ -357,6 +367,8 @@ private void ReadNextRecord() } else { + // mark end of file + mEof = true; mLastRecordValues = null; mLastRecord = default(T); @@ -400,9 +412,15 @@ public T[] ReadNexts(int numberOfRecords) { ReadNextRecord(); if (mLastRecord != null) - arr.Add(mLastRecord); + { + arr.Add(mLastRecord); + } else + { + // mark end of file + mEof = true; break; + } } return arr.ToArray(); } @@ -447,17 +465,19 @@ public void Close() try { - var writer = mAsyncWriter; - if (writer != null) + using (var writer = mAsyncWriter) { - if (!string.IsNullOrEmpty(mFooterText)) - if (mFooterText.EndsWith(StringHelper.NewLine)) - writer.Write(mFooterText); - else - writer.WriteLine(mFooterText); - - writer.Close(); - mAsyncWriter = null; + mAsyncWriter = null; + if (writer != null) + { + if (!string.IsNullOrEmpty (mFooterText)) + if (mFooterText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) + writer.Write (mFooterText); + else + writer.WriteLine (mFooterText); + + writer.Close (); + } } } catch @@ -499,7 +519,7 @@ public IDisposable BeginWriteStream(TextWriter writer) private void WriteHeader() { if (!string.IsNullOrEmpty(mHeaderText)) - if (mHeaderText.EndsWith(StringHelper.NewLine)) + if (mHeaderText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) mAsyncWriter.Write(mHeaderText); else mAsyncWriter.WriteLine(mHeaderText); diff --git a/FileHelpers/Engines/FileHelperEngine.cs b/FileHelpers/Engines/FileHelperEngine.cs index e72972c32..c1ec17892 100644 --- a/FileHelpers/Engines/FileHelperEngine.cs +++ b/FileHelpers/Engines/FileHelperEngine.cs @@ -477,7 +477,7 @@ public void WriteStream(TextWriter writer, IEnumerable records, int maxRecord ResetFields(); if (!string.IsNullOrEmpty(mHeaderText)) - if (mHeaderText.EndsWith(StringHelper.NewLine)) + if (mHeaderText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) writer.Write(mHeaderText); else writer.WriteLine(mHeaderText); @@ -563,7 +563,7 @@ public void WriteStream(TextWriter writer, IEnumerable records, int maxRecord mTotalRecords = recIndex; if (!string.IsNullOrEmpty(mFooterText)) - if (mFooterText.EndsWith(StringHelper.NewLine)) + if (mFooterText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) writer.Write(mFooterText); else writer.WriteLine(mFooterText); diff --git a/FileHelpers/Engines/MultiRecordEngine.cs b/FileHelpers/Engines/MultiRecordEngine.cs index b681eaa07..6b1acda90 100644 --- a/FileHelpers/Engines/MultiRecordEngine.cs +++ b/FileHelpers/Engines/MultiRecordEngine.cs @@ -422,7 +422,7 @@ public void WriteStream(TextWriter writer, IEnumerable records, int maxRecords) ResetFields(); if (!string.IsNullOrEmpty(mHeaderText)) - if (mHeaderText.EndsWith(StringHelper.NewLine)) + if (mHeaderText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) writer.Write(mHeaderText); else writer.WriteLine(mHeaderText); @@ -504,7 +504,7 @@ public void WriteStream(TextWriter writer, IEnumerable records, int maxRecords) mTotalRecords = recIndex; if (!string.IsNullOrEmpty(mFooterText)) - if (mFooterText.EndsWith(StringHelper.NewLine)) + if (mFooterText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) writer.Write(mFooterText); else writer.WriteLine(mFooterText); @@ -701,7 +701,7 @@ public void Close() if (mAsyncWriter != null) { if (!string.IsNullOrEmpty(mFooterText)) - if (mFooterText.EndsWith(StringHelper.NewLine)) + if (mFooterText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) mAsyncWriter.Write(mFooterText); else mAsyncWriter.WriteLine(mFooterText); @@ -1036,7 +1036,7 @@ public void BeginWriteStream(TextWriter writer) private void WriteHeader() { if (!string.IsNullOrEmpty(mHeaderText)) - if (mHeaderText.EndsWith(StringHelper.NewLine)) + if (mHeaderText.EndsWith (StringHelper.NewLine, StringComparison.Ordinal)) mAsyncWriter.Write(mHeaderText); else mAsyncWriter.WriteLine(mHeaderText); diff --git a/FileHelpers/ErrorHandling/ErrorManager.cs b/FileHelpers/ErrorHandling/ErrorManager.cs index 61e2663b2..57795a078 100644 --- a/FileHelpers/ErrorHandling/ErrorManager.cs +++ b/FileHelpers/ErrorHandling/ErrorManager.cs @@ -15,6 +15,8 @@ namespace FileHelpers public sealed class ErrorManager :IEnumerable { + private int mErrorLimit = 10000; + /// /// Initializes a new instance of the class. /// @@ -32,8 +34,15 @@ public ErrorManager(ErrorMode mode) mErrorMode = mode; } + /// Maximum number of recorded errors. After this limit is reached, successive errors are ignored. + /// Default error limit is 10000. + public int ErrorLimit + { + get { return mErrorLimit; } + set { mErrorLimit = value; } + } - private string ErrorsDescription() + private string ErrorsDescription () { if (ErrorCount == 1) return ErrorCount.ToString() + " Error"; @@ -44,7 +53,7 @@ private string ErrorsDescription() } [DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly ArrayList mErrorsArray = new ArrayList(); + List mErrorsArray = new List(); /// /// Is an array of that contains the @@ -53,7 +62,7 @@ private string ErrorsDescription() [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public ErrorInfo[] Errors { - get { return (ErrorInfo[]) mErrorsArray.ToArray(typeof (ErrorInfo)); } + get { return mErrorsArray.ToArray(); } } @@ -65,13 +74,13 @@ public ErrorInfo[] Errors /// Indicates the behavior of the /// when it found an error. /// + /// Default error mode is ThrowException. public ErrorMode ErrorMode { get { return mErrorMode; } set { mErrorMode = value; } } - /// Number of contained errors. public int ErrorCount { @@ -94,13 +103,15 @@ public void ClearErrors() /// internal void AddError(ErrorInfo error) { - mErrorsArray.Add(error); + if (mErrorsArray.Count <= mErrorLimit) + mErrorsArray.Add(error); } /// Add the specified ErrorInfo to the contained collection. internal void AddErrors(ErrorManager errors) { - mErrorsArray.AddRange(errors.mErrorsArray); + if (mErrorsArray.Count <= mErrorLimit) + mErrorsArray.AddRange(errors.mErrorsArray); } // public void ProcessError(Exception ex, string line) @@ -131,7 +142,7 @@ public void SaveErrors(string fileName, string header) { var engine = new FileHelperEngine(typeof (ErrorInfo)); - if (header.IndexOf(StringHelper.NewLine) == header.LastIndexOf(StringHelper.NewLine)) + if (header.IndexOf (StringHelper.NewLine, StringComparison.Ordinal) == header.LastIndexOf (StringHelper.NewLine, StringComparison.Ordinal)) header += StringHelper.NewLine; engine.HeaderText = header; diff --git a/FileHelpers/Fields/DelimitedField.cs b/FileHelpers/Fields/DelimitedField.cs index 9b0feeebe..7d1d247a7 100644 --- a/FileHelpers/Fields/DelimitedField.cs +++ b/FileHelpers/Fields/DelimitedField.cs @@ -48,10 +48,10 @@ internal DelimitedField(FieldInfo fi, string sep) /// Set the separator string /// /// Also sets the discard count - internal string Separator + public string Separator { get { return mSeparator; } - set + internal set { mSeparator = value; @@ -65,17 +65,17 @@ internal string Separator /// /// allow a quoted multiline format /// - internal MultilineMode QuoteMultiline { get; set; } + public MultilineMode QuoteMultiline { get; internal set; } /// /// whether quotes are optional for read and / or write /// - internal QuoteMode QuoteMode { get; set; } + public QuoteMode QuoteMode { get; internal set; } /// /// quote character around field (and repeated within it) /// - internal char QuoteChar { get; set; } + public char QuoteChar { get; internal set; } #endregion diff --git a/FileHelpers/Fields/FieldBase.cs b/FileHelpers/Fields/FieldBase.cs index 013615f5a..3fac1b2e1 100644 --- a/FileHelpers/Fields/FieldBase.cs +++ b/FileHelpers/Fields/FieldBase.cs @@ -43,107 +43,105 @@ public abstract class FieldBase /// Field type of an array or it is just fieldType. /// What actual object will be created /// - internal Type FieldTypeInternal { get; set; } + public Type FieldTypeInternal { get; internal set; } /// /// Is this field an array? /// - public bool IsArray { get; private set; } + public bool IsArray { get; internal set; } /// /// Array must have this many entries /// - public int ArrayMinLength { get; set; } + public int ArrayMinLength { get; internal set; } /// /// Array may have this many entries, if equal to ArrayMinLength then /// it is a fixed length array /// - public int ArrayMaxLength { get; set; } + public int ArrayMaxLength { get; internal set; } /// /// Seems to be duplicate of FieldTypeInternal except it is ONLY set /// for an array /// - internal Type ArrayType { get; set; } - + public Type ArrayType { get; internal set; } /// /// Am I the first field in an array list /// - internal bool IsFirst { get; set; } + public bool IsFirst { get; internal set; } /// /// Am I the last field in the array list /// - internal bool IsLast { get; set; } + public bool IsLast { get; internal set; } /// /// Do we process this field but not store the value /// - public bool Discarded { get; set; } + public bool Discarded { get; internal set; } /// /// Unused! /// - internal bool TrailingArray { get; set; } + public bool TrailingArray { get; internal set; } /// /// Value to use if input is null or empty /// - internal object NullValue { get; set; } + public object NullValue { get; internal set; } /// /// Are we a simple string field we can just assign to /// - internal bool IsStringField { get; set; } + public bool IsStringField { get; internal set; } /// /// Details about the extraction criteria /// - internal FieldInfo FieldInfo { get; set; } - + public FieldInfo FieldInfo { get; internal set; } /// /// indicates whether we trim leading and/or trailing whitespace /// - public TrimMode TrimMode { get; set; } + public TrimMode TrimMode { get; internal set; } /// /// Character to chop off front and / rear of the string /// - internal char[] TrimChars { get; set; } + public char[] TrimChars { get; internal set; } /// /// The field may not be present on the input data (line not long enough) /// - public bool IsOptional { get; set; } + public bool IsOptional { get; internal set; } /// /// The next field along is optional, optimise processing next records /// - internal bool NextIsOptional { get; set; } + public bool NextIsOptional { get; internal set; } /// /// Set from the FieldInNewLIneAtribute. This field begins on a new /// line of the file /// - internal bool InNewLine { get; set; } + public bool InNewLine { get; internal set; } /// /// Order of the field in the file layout /// - internal int? FieldOrder { get; set; } + public int? FieldOrder { get; internal set; } /// /// Can null be assigned to this value type, for example not int or /// DateTime /// - internal bool IsNullableType { get; private set; } + public bool IsNullableType { get; private set; } /// /// Name of the field without extra characters (eg property) /// - internal string FieldFriendlyName { get; set; } + public string FieldFriendlyName { get; internal set; } // -------------------------------------------------------------- // WARNING !!! @@ -153,7 +151,7 @@ public abstract class FieldBase /// /// Fieldname of the field we are storing /// - internal string FieldName + public string FieldName { get { return FieldInfo.Name; } } @@ -313,9 +311,9 @@ public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAtt if (fi.IsDefined(typeof(CompilerGeneratedAttribute), false)) { - if (fi.Name.EndsWith("__BackingField") && fi.Name.StartsWith("<") && fi.Name.Contains(">")) + if (fi.Name.EndsWith ("__BackingField", StringComparison.Ordinal) && fi.Name.StartsWith ("<", StringComparison.Ordinal) && fi.Name.Contains (">")) { - res.FieldFriendlyName = fi.Name.Substring(1, fi.Name.IndexOf(">") - 1); + res.FieldFriendlyName = fi.Name.Substring (1, fi.Name.IndexOf('>') - 1); } } diff --git a/FileHelpers/Fields/FixedLengthField.cs b/FileHelpers/Fields/FixedLengthField.cs index 61f37a942..28624c2c8 100644 --- a/FileHelpers/Fields/FixedLengthField.cs +++ b/FileHelpers/Fields/FixedLengthField.cs @@ -18,17 +18,17 @@ public sealed class FixedLengthField /// /// Field length of this field in the record /// - internal int FieldLength { get; private set; } + public int FieldLength { get; private set; } /// /// Alignment of this record /// - internal FieldAlignAttribute Align { get; private set; } + public FieldAlignAttribute Align { get; private set; } /// /// Whether we allow more or less characters to be handled /// - internal FixedMode FixedMode { get; set; } + public FixedMode FixedMode { get; internal set; } #endregion diff --git a/FileHelpers/FileHelpers.xml b/FileHelpers/FileHelpers.xml index 1f89df349..4dc634417 100644 --- a/FileHelpers/FileHelpers.xml +++ b/FileHelpers/FileHelpers.xml @@ -6987,6 +6987,12 @@ Destructor + + + Indicates if End of File was reached. + + The EOF flag. + Contains the last Record read by the method. This example shows a simple example of use of the async methods in the FileHelperAsymcEngine: diff --git a/FileHelpers/FormatDetector/QuoteHelper.cs b/FileHelpers/FormatDetector/QuoteHelper.cs index 4d96e564b..bffbac1be 100644 --- a/FileHelpers/FormatDetector/QuoteHelper.cs +++ b/FileHelpers/FormatDetector/QuoteHelper.cs @@ -22,7 +22,7 @@ public static int CountNumberOfDelimiters(string line, char delimiter, char quot var restOfLine = line; while (!string.IsNullOrEmpty(restOfLine)) { - if (restOfLine.StartsWith(quotedChar.ToString())) + if (restOfLine.StartsWith (quotedChar.ToString (), StringComparison.Ordinal)) { restOfLine = DiscardUntilQuotedChar(restOfLine, quotedChar); } @@ -54,7 +54,7 @@ public static int CountNumberOfDelimiters(string line, char delimiter, char quot /// private static string DiscardUntilQuotedChar(string line, char quoteChar) { - if (line.StartsWith(quoteChar.ToString())) + if (line.StartsWith (quoteChar.ToString (), StringComparison.Ordinal)) line = line.Substring(1); var index = line.IndexOf(quoteChar); diff --git a/FileHelpers/Helpers/ConditionHelper.cs b/FileHelpers/Helpers/ConditionHelper.cs index 710131b74..b2a284c67 100644 --- a/FileHelpers/Helpers/ConditionHelper.cs +++ b/FileHelpers/Helpers/ConditionHelper.cs @@ -17,7 +17,7 @@ internal static class ConditionHelper /// true if string begins with the selector public static bool BeginsWith(string line, string selector) { - return line.StartsWith(selector); + return line.StartsWith (selector, StringComparison.Ordinal); } /// @@ -28,7 +28,7 @@ public static bool BeginsWith(string line, string selector) /// true if string ends with the selector public static bool EndsWith(string line, string selector) { - return line.EndsWith(selector); + return line.EndsWith (selector, StringComparison.Ordinal); } /// @@ -39,7 +39,7 @@ public static bool EndsWith(string line, string selector) /// true if string contains the selector public static bool Contains(string line, string selector) { - return line.IndexOf(selector) >= 0; + return line.IndexOf (selector, 0, StringComparison.Ordinal) >= 0; } /// @@ -50,7 +50,7 @@ public static bool Contains(string line, string selector) /// true if string begins and ends with the selector public static bool Enclosed(string line, string selector) { - return line.StartsWith(selector) && line.EndsWith(selector); + return line.StartsWith (selector, StringComparison.Ordinal) && line.EndsWith (selector, StringComparison.Ordinal); } } } diff --git a/FileHelpers/Helpers/StringHelper.cs b/FileHelpers/Helpers/StringHelper.cs index 64486ee9f..aa4d0b384 100644 --- a/FileHelpers/Helpers/StringHelper.cs +++ b/FileHelpers/Helpers/StringHelper.cs @@ -145,14 +145,15 @@ internal static string RemoveBlanks(string source) { int i = 0; + int sz = source.Length; - while (i < source.Length && char.IsWhiteSpace(source[i])) + while (i < sz && char.IsWhiteSpace(source[i])) { i++; } // Only whitespace return an empty string - if (i >= source.Length) + if (i >= sz) return string.Empty; // we are looking for a gap after the sign, if not found then @@ -164,14 +165,14 @@ internal static string RemoveBlanks(string source) return source; // sign is followed by text so just return it // start out with the sign - var sb = new StringBuilder(source[i - 1].ToString()); + var sb = new StringBuilder (source[i - 1].ToString (), sz - i); i++; // I am on whitepsace so skip it - while (i < source.Length && char.IsWhiteSpace(source[i])) + while (i < sz && char.IsWhiteSpace(source[i])) { i++; } - if (i < source.Length) + if (i < sz) sb.Append(source.Substring(i)); return sb.ToString(); @@ -301,5 +302,21 @@ public static string Replace(string original, string oldValue, string newValue, return result; } + + public static bool IsNullOrWhiteSpace (string value) + { + if (value == null) + { + return true; + } + for (int i = 0; i < value.Length; i++) + { + if (!char.IsWhiteSpace (value[i])) + { + return false; + } + } + return true; + } } } \ No newline at end of file diff --git a/FileHelpers/MasterDetail/MasterDetailEngine.cs b/FileHelpers/MasterDetail/MasterDetailEngine.cs index 562425a94..3c69ad6df 100644 --- a/FileHelpers/MasterDetail/MasterDetailEngine.cs +++ b/FileHelpers/MasterDetail/MasterDetailEngine.cs @@ -121,49 +121,49 @@ internal RecordAction CommonSelectorMethod(string recordString) switch(mAction) { case CommonSelector.DetailIfContains: - if (recordString.IndexOf(mSelector) >= 0) + if (recordString.IndexOf (mSelector, StringComparison.Ordinal) >= 0) return RecordAction.Detail; else return RecordAction.Master; case CommonSelector.MasterIfContains: - if (recordString.IndexOf(mSelector) >= 0) + if (recordString.IndexOf (mSelector, StringComparison.Ordinal) >= 0) return RecordAction.Master; else return RecordAction.Detail; case CommonSelector.DetailIfBegins: - if (recordString.StartsWith(mSelector)) + if (recordString.StartsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Detail; else return RecordAction.Master; case CommonSelector.MasterIfBegins: - if (recordString.StartsWith(mSelector)) + if (recordString.StartsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Master; else return RecordAction.Detail; case CommonSelector.DetailIfEnds: - if (recordString.EndsWith(mSelector)) + if (recordString.EndsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Detail; else return RecordAction.Master; case CommonSelector.MasterIfEnds: - if (recordString.EndsWith(mSelector)) + if (recordString.EndsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Master; else return RecordAction.Detail; case CommonSelector.DetailIfEnclosed: - if (recordString.StartsWith(mSelector) && recordString.EndsWith(mSelector)) + if (recordString.StartsWith (mSelector, StringComparison.Ordinal) && recordString.EndsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Detail; else return RecordAction.Master; case CommonSelector.MasterIfEnclosed: - if (recordString.StartsWith(mSelector) && recordString.EndsWith(mSelector)) + if (recordString.StartsWith (mSelector, StringComparison.Ordinal) && recordString.EndsWith (mSelector, StringComparison.Ordinal)) return RecordAction.Master; else return RecordAction.Detail; @@ -528,7 +528,7 @@ public void WriteStream(TextWriter writer, IEnumerable