LineOffsets (final @NotNull CharBuffer buffer, final long modificationStamp) { int dst = 0; char prev = ' '; int crlfCount = 0; final IntList originalLineOffsets = new IntArrayList(); final IntList convertedLineOffsets = new IntArrayList(); // first line originalLineOffsets.add(0); convertedLineOffsets.add(0); final int length = buffer.length(); final char[] bufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer); for (int src = 0; src < length; src++) { char c = bufferArray != null ? bufferArray[src] : buffer.charAt(src); switch (c) { case '\r' -> { if (bufferArray != null) { bufferArray[dst++] = '\n'; } else { buffer.put(dst++, '\n'); } //crCount++; originalLineOffsets.add(dst + crlfCount); convertedLineOffsets.add(dst); } case '\n' -> { if (prev == '\r') { //crCount--; crlfCount++; originalLineOffsets.set(originalLineOffsets.size() - 1, dst + crlfCount); } else { if (bufferArray != null) { bufferArray[dst++] = '\n'; } else { buffer.put(dst++, '\n'); } //lfCount++; originalLineOffsets.add(dst + crlfCount); convertedLineOffsets.add(dst); } } default -> { if (bufferArray != null) { bufferArray[dst++] = c; } else { buffer.put(dst++, c); } } } prev = c; } return new LineOffsets(modificationStamp, originalLineOffsets.toIntArray(), convertedLineOffsets.toIntArray()); }