public static ILineBreaks CreateLineBreaks(string source) { IPooledLineBreaksEditor lineBreaks = null; int index = 0; while (index < source.Length) { int breakLength = TextUtilities.LengthOfLineBreak(source, index, source.Length); if (breakLength == 0) { ++index; } else { if (lineBreaks == null) { lineBreaks = LineBreakManager.CreatePooledLineBreakEditor(source.Length); } lineBreaks.Add(index, breakLength); index += breakLength; } } if (lineBreaks != null) { lineBreaks.ReleasePooledLineBreaks(); return(lineBreaks); } return(Empty); }
// Evil performance hack (but we are on a hot path here): // thresholdForInvalidCharacters should be '\u0001' if we are throwing on invalid characters. // should be '\0' if we are not. // (otherwise we need to check both a throwOnInvalidCharacters boolean and that c == 0). private static ILineBreaks ParseBlock(char[] buffer, int length, char thresholdForInvalidCharacters, ref NewlineState newlineState, ref LeadingWhitespaceState leadingWhitespaceState, ref int currentLineLength, ref int longestLineLength, ref bool nextCharIsStartOfLine) { // Note that the lineBreaks created here will (internally) use the pooled list of line breaks. IPooledLineBreaksEditor lineBreaks = LineBreakManager.CreatePooledLineBreakEditor(length); int index = 0; while (index < length) { int breakLength = TextUtilities.LengthOfLineBreak(buffer, index, length); if (breakLength == 0) { char c = buffer[index]; // If we are checking for invalid characters, throw if we encounter a \0 if (c < thresholdForInvalidCharacters) { throw new FileFormatException("File contains NUL characters"); } ++currentLineLength; ++index; if (nextCharIsStartOfLine) { switch (c) { case ' ': leadingWhitespaceState.Increment(LeadingWhitespaceState.LineLeadingCharacter.Space, 1); break; case '\t': leadingWhitespaceState.Increment(LeadingWhitespaceState.LineLeadingCharacter.Tab, 1); break; default: leadingWhitespaceState.Increment(LeadingWhitespaceState.LineLeadingCharacter.Printable, 1); break; } nextCharIsStartOfLine = false; } } else { lineBreaks.Add(index, breakLength); longestLineLength = Math.Max(longestLineLength, currentLineLength); currentLineLength = 0; if (breakLength == 2) { newlineState.Increment(NewlineState.LineEnding.CRLF, 1); } else { switch (buffer[index]) { // This code needs to be kep consistent with TextUtilities.LengthOfLineBreak() case '\r': newlineState.Increment(NewlineState.LineEnding.CR, 1); break; case '\n': newlineState.Increment(NewlineState.LineEnding.LF, 1); break; case '\u0085': newlineState.Increment(NewlineState.LineEnding.NEL, 1); break; case '\u2028': newlineState.Increment(NewlineState.LineEnding.LS, 1); break; case '\u2029': newlineState.Increment(NewlineState.LineEnding.PS, 1); break; default: throw new InvalidOperationException("Unexpected line ending"); } } if (nextCharIsStartOfLine) { leadingWhitespaceState.Increment(LeadingWhitespaceState.LineLeadingCharacter.Empty, 1); } nextCharIsStartOfLine = true; } index += breakLength; } lineBreaks.ReleasePooledLineBreaks(); return(lineBreaks); }
private static ILineBreaks ParseBlock(char[] buffer, int length, ref LineEndingState lineEnding, ref int currentLineLength, ref int longestLineLength) { // Note that the lineBreaks created here will (internally) use the pooled list of line breaks. IPooledLineBreaksEditor lineBreaks = LineBreakManager.CreatePooledLineBreakEditor(length); int index = 0; while (index < length) { int breakLength = TextUtilities.LengthOfLineBreak(buffer, index, length); if (breakLength == 0) { ++currentLineLength; ++index; } else { lineBreaks.Add(index, breakLength); longestLineLength = Math.Max(longestLineLength, currentLineLength); currentLineLength = 0; if (lineEnding != LineEndingState.Inconsistent) { if (breakLength == 2) { if (lineEnding == LineEndingState.Unknown) { lineEnding = LineEndingState.CRLF; } else if (lineEnding != LineEndingState.CRLF) { lineEnding = LineEndingState.Inconsistent; } } else { LineEndingState newLineEndingState; switch (buffer[index]) { // This code needs to be kep consistent with TextUtilities.LengthOfLineBreak() case '\r': newLineEndingState = LineEndingState.CR; break; case '\n': newLineEndingState = LineEndingState.LF; break; case '\u0085': newLineEndingState = LineEndingState.NEL; break; case '\u2028': newLineEndingState = LineEndingState.LS; break; case '\u2029': newLineEndingState = LineEndingState.PS; break; default: throw new InvalidOperationException("Unexpected line ending"); } if (lineEnding == LineEndingState.Unknown) { lineEnding = newLineEndingState; } else if (lineEnding != newLineEndingState) { lineEnding = LineEndingState.Inconsistent; } } } index += breakLength; } } lineBreaks.ReleasePooledLineBreaks(); return(lineBreaks); }