public ExtractedInfo(LineInfo line, int extractTo) { mLine = line; ExtractedFrom = line.mCurrentPos; ExtractedTo = extractTo - 1; //CharsRemoved = ExtractedTo - ExtractedFrom + 1; //ExtraLines = 0; // NewRestOfLine = null; }
protected override ExtractedInfo ExtractFieldString(LineInfo line) { if (mIsOptional && line.IsEOL()) return ExtractedInfo.Empty; if (mQuoteChar == '\0') return BasicExtractString(line); else { //TODO: UnComment and Fix if (mTrimMode == TrimMode.Both || mTrimMode == TrimMode.Left) { //int pos = line.mCurrentPos; line.TrimStart(mTrimChars); // from2 = from.TrimStart(mTrimChars); //res.CharsRemoved = line.mCurrentPos - pos; } var quotedStr = mQuoteChar.ToString(); if (line.StartsWith(quotedStr)) { // ExtractedInfo res = null; // res = new ExtractedInfo(line, line.mCurrentPos); return StringHelper.ExtractQuotedString(line, mQuoteChar, mQuoteMultiline == MultilineMode.AllowForBoth || mQuoteMultiline == MultilineMode.AllowForRead); // if (mQuoteMultiline == MultilineMode.AllowForBoth || mQuoteMultiline == MultilineMode.AllowForRead) // { // // //res.ExtractedString = ei.ExtractedString; // //res.CharsRemoved += ei.CharsRemoved; // //res.ExtraLines = ei.ExtraLines; // //res.NewRestOfLine = ei.NewRestOfLine; // } // else // { // return StringHelper.ExtractQuotedString(from2, mQuoteChar, out index); // //res.CharsRemoved += index; // } // return res; } else { if (mQuoteMode == QuoteMode.OptionalForBoth || mQuoteMode == QuoteMode.OptionalForRead) return BasicExtractString(line); else if (line.StartsWithTrim(quotedStr)) throw new BadUsageException("The field '" + mFieldInfo.Name + "' has spaces before the QuotedChar at line " + line.mReader.LineNumber.ToString() + ". Use the TrimAttribute to by pass this error. Field String: " + line.CurrentString); else throw new BadUsageException("The field '" + mFieldInfo.Name + "' not begin with the QuotedChar at line " + line.mReader.LineNumber.ToString() + ". You can use FieldQuoted(QuoteMode.OptionalForRead) to allow optional quoted field.. Field String: " + line.CurrentString); } } }
protected override ExtractedInfo ExtractFieldString(LineInfo line) { if (line.CurrentLength == 0) { if (mIsOptional) return ExtractedInfo.Empty; else throw new BadUsageException("End Of Line found processing the field: " + mFieldInfo.Name + " at line " + line.mReader.LineNumber.ToString() + ". (You need to mark it as [FieldOptional] if you want to avoid this exception)"); } ExtractedInfo res; if (line.CurrentLength < mFieldLength) if (mFixedMode == FixedMode.AllowLessChars || mFixedMode == FixedMode.AllowVariableLength) res = new ExtractedInfo(line); else throw new BadUsageException("The string '" + line.CurrentString + "' (length " + line.CurrentLength.ToString() + ") at line " + line.mReader.LineNumber.ToString() + " has less chars than the defined for " + mFieldInfo.Name + " (" + mFieldLength.ToString() + "). You can use the [FixedLengthRecord(FixedMode.AllowLessChars)] to avoid this problem."); else if (mIsLast && line.CurrentLength > mFieldLength && mFixedMode != FixedMode.AllowMoreChars && mFixedMode != FixedMode.AllowVariableLength) throw new BadUsageException("The string '" + line.CurrentString + "' (length " + line.CurrentLength.ToString() + ") at line " + line.mReader.LineNumber.ToString() + " has more chars than the defined for the last field " + mFieldInfo.Name + " (" + mFieldLength.ToString() + ").You can use the [FixedLengthRecord(FixedMode.AllowMoreChars)] to avoid this problem."); else res = new ExtractedInfo(line, line.mCurrentPos + mFieldLength); return res; }
private ExtractedInfo BasicExtractString(LineInfo line) { ExtractedInfo res; if (mIsLast) res = new ExtractedInfo(line); else { int sepPos; sepPos = line.IndexOf(mSeparator); if (sepPos == -1) { if (mNextIsOptional == false) { string msg = null; if (mIsFirst && line.EmptyFromPos()) msg = "The line " + line.mReader.LineNumber.ToString() + " is empty. Maybe you need to use the attribute [IgnoreEmptyLines] in your record class."; else msg = "The delimiter '" + mSeparator + "' can´t be found after the field '" + mFieldInfo.Name + "' at line " + line.mReader.LineNumber.ToString() + " (the record has less fields, the delimiter is wrong or the next field must be marked as optional)."; throw new FileHelpersException(msg); } else sepPos = line.mLine.Length - 1; } res = new ExtractedInfo(line, sepPos); } return res; }
internal object StringToRecord(LineInfo line) { if (MustIgnoreLine(line.mLineStr)) return null; var mValues = new object[mFieldCount]; // array that holds the fields values for (var i = 0; i < mFieldCount; i++) { mValues[i] = mFields[i].ExtractValue(line); } CreateAssingMethods(); try { // Asign all values via dinamic method that creates an object and assign values return mCreateHandler(mValues); } catch (InvalidCastException) { // Occurrs when the a custom converter returns an invalid value for the field. for (var i = 0; i < mFieldCount; i++) { if (mValues[i] != null && ! mFields[i].mFieldType.IsInstanceOfType(mValues[i])) throw new ConvertException(null, mFields[i].mFieldType, mFields[i].mFieldInfo.Name, line.mReader.LineNumber, -1, "The converter for the field: " + mFields[i].mFieldInfo.Name + " returns an object of Type: " + mValues[i].GetType().Name + " and the field is of type: " + mFields[i].mFieldType.Name); } return null; } }
internal static ExtractedInfo ExtractQuotedString(LineInfo line, char quoteChar, bool allowMultiline) { // if (line.mReader == null) // throw new BadUsageException("The reader can´t be null"); if (line.IsEOL()) throw new BadUsageException("An empty String found and can be parsed like a QuotedString try to use SafeExtractQuotedString"); if (line.mLine[line.mCurrentPos] != quoteChar) throw new BadUsageException("The source string not begins with the quote char: " + quoteChar); var res = new StringBuilder(32); //int lines = 0; var firstFound = false; var i = line.mCurrentPos + 1; //bool mustContinue = true; while (line.mLineStr != null) { while (i < line.mLine.Length) { if (line.mLine[i] == quoteChar) { if (firstFound) { // Is an escaped quoted char res.Append(quoteChar); firstFound = false; } else { firstFound = true; } } else { if (firstFound) { // This was the end of the string line.mCurrentPos = i; return new ExtractedInfo(res.ToString()); // ExtractedInfo ei = ; // return ei; } else { res.Append(line.mLine[i]); } } i++; } if (firstFound) { line.mCurrentPos = i; return new ExtractedInfo(res.ToString()); } else { if (allowMultiline == false) throw new BadUsageException("The current field has an UnClosed quoted string. Complete line: " + res); line.ReadNextLine(); res.Append(NewLine); //lines++; i = 0; } } throw new BadUsageException("The current field has an unclosed quoted string. Complete Filed String: " + res); }
internal object AssignFromString(ExtractedInfo fieldString, LineInfo line) { object val; switch (mTrimMode) { case TrimMode.None: break; case TrimMode.Both: fieldString.TrimBoth(mTrimChars); break; case TrimMode.Left: fieldString.TrimStart(mTrimChars); break; case TrimMode.Right: fieldString.TrimEnd(mTrimChars); break; } try { if (mConvertProvider == null) { if (mIsStringField) val = fieldString.ExtractedString(); else { // Trim it to use Convert.ChangeType fieldString.TrimBoth(WhitespaceChars); if (fieldString.Length == 0) { // Empty stand for null val = GetNullValue(); } else { val = Convert.ChangeType(fieldString.ExtractedString(), mFieldType, null); } } } else { if (mConvertProvider.CustomNullHandling == false && fieldString.HasOnlyThisChars(WhitespaceChars)) { val = GetNullValue(); } else { var from = fieldString.ExtractedString(); val = mConvertProvider.StringToField(from); if (val == null) val = GetNullValue(); } } return val; } catch (ConvertException ex) { var e = ConvertException.ReThrowException(ex, mFieldInfo.Name, line.mReader.LineNumber, fieldString.ExtractedFrom + 1); throw e; } }
// object[] values, int index, ForwardReader reader internal object ExtractValue(LineInfo line) { //-> extract only what I need if (mInNewLine) { if (line.EmptyFromPos() == false) throw new BadUsageException("Text '" + line.CurrentString + "' found before the new line of the field: " + mFieldInfo.Name + " (this is not allowed when you use [FieldInNewLine])"); line.ReLoad(line.mReader.ReadNextLine()); if (line.mLineStr == null) throw new BadUsageException("End of stream found parsing the field " + mFieldInfo.Name + ". Please check the class record."); } var info = ExtractFieldString(line); if (info.mCustomExtractedString == null) line.mCurrentPos = info.ExtractedTo + 1; line.mCurrentPos += mCharsToDiscard; //total; return AssignFromString(info, line); //-> discard the part that I use //TODO: Uncoment this for Quoted Handling // if (info.NewRestOfLine != null) // { // if (info.NewRestOfLine.Length < CharsToDiscard()) // return info.NewRestOfLine; // else // return info.NewRestOfLine.Substring(CharsToDiscard()); // } // else // { // int total; // if (info.CharsRemoved >= line.mLine.Length) // total = line.mLine.Length; // else // total = info.CharsRemoved + CharsToDiscard(); //return buffer.Substring(total); // } }
protected abstract ExtractedInfo ExtractFieldString(LineInfo line);