// whitespace processing needs to happen in two phases. the first is where we collapse whitespace and handle new lines // the second is what to do with trailing space and wrapping. public static int ProcessWhitespace(WhitespaceMode whitespaceMode, ref char[] buffer, char[] input, int inputSize = -1) { if (inputSize < 0) { inputSize = input.Length; } if (inputSize == 0) { return(0); } bool collapseSpaceAndTab = (whitespaceMode & WhitespaceMode.CollapseWhitespace) != 0; bool preserveNewLine = (whitespaceMode & WhitespaceMode.PreserveNewLines) != 0; bool trimStart = (whitespaceMode & WhitespaceMode.TrimStart) != 0; bool trimEnd = (whitespaceMode & WhitespaceMode.TrimEnd) != 0; bool collapsing = false; if (buffer == null) { buffer = ArrayPool <char> .GetMinSize(inputSize); } if (buffer.Length < inputSize) { ArrayPool <char> .Resize(ref buffer, inputSize); } int writeIndex = 0; int start = 0; int end = inputSize; if (trimStart) { for (int i = 0; i < end; i++) { char c = input[i]; bool isWhiteSpace = c == ' ' || c >= '\t' && c <= '\r' || (c == ' ' || c == '\x0085'); if (!isWhiteSpace) { start = i; break; } } } if (trimEnd) { for (int i = end - 1; i >= start; i--) { char c = input[i]; bool isWhiteSpace = c == ' ' || c >= '\t' && c <= '\r' || (c == ' ' || c == '\x0085'); if (!isWhiteSpace) { end = i + 1; break; } } } for (int i = start; i < end; i++) { char c = input[i]; if (c == '\n' && !preserveNewLine) { continue; } bool isWhiteSpace = c == ' ' || c >= '\t' && c <= '\r' || (c == ' ' || c == '\x0085'); if (c == '\n') { if (preserveNewLine) { buffer[writeIndex++] = c; continue; } } if (collapsing) { if (!isWhiteSpace) { buffer[writeIndex++] = c; collapsing = false; } } else if (isWhiteSpace) { collapsing = collapseSpaceAndTab; buffer[writeIndex++] = ' '; } else { buffer[writeIndex++] = c; } } return(writeIndex); }