ConvertResult (byte @NotNull [] charsAsBytes, int startOffset, int endOffset) { int lineBreak = findLineBreakOrWideChar(charsAsBytes, startOffset, endOffset); if (!BitUtil.isSet(lineBreak, CR) && !BitUtil.isSet(lineBreak, WIDE)) { // optimisation: if there is no CR in the file, no line separator conversion is necessary. we can re-use the passed byte buffer inplace ByteArrayCharSequence sequence = new ByteArrayCharSequence(charsAsBytes, startOffset, endOffset); return new ConvertResult(sequence, 0, BitUtil.isSet(lineBreak, LF) ? 1 : 0, 0); } if (BitUtil.isSet(lineBreak, WIDE)) { // characters outside AS_ASCII range found, insert UNDEFINED_CHAR return convertWideCharacters(charsAsBytes, startOffset, endOffset); } // convert \r\n to \n, \r to \n int dst = 0; char prev = ' '; int crCount = 0; int lfCount = 0; int crlfCount = 0; byte[] result = ArrayUtil.newByteArray(endOffset - startOffset); for (int src = startOffset; src < endOffset; src++) { char c = (char)charsAsBytes[src]; switch (c) { case '\r': result[dst++] = '\n'; crCount++; break; case '\n': if (prev == '\r') { crCount--; crlfCount++; } else { result[dst++] = '\n'; lfCount++; } break; default: result[dst++] = (byte)c; break; } prev = c; } ByteArrayCharSequence sequence = new ByteArrayCharSequence(result, 0, dst); return new ConvertResult(sequence, crCount, lfCount, crlfCount); }