public int copyTo(@Nullable char[] buffer, int start) { final int length = myText.length(); if (buffer != null) { CharArrayUtil.getChars(myText, buffer, start, length); } return start + length; }
@Override @NotNull public char[] textToCharArray() { final char[] buffer = new char[myText.length()]; CharArrayUtil.getChars(myText, buffer, 0); return buffer; }
private void prepareForModification() { if (myOriginalSequence != null) { myArray = new char[myOriginalSequence.length()]; CharArrayUtil.getChars(myOriginalSequence, myArray, 0); myOriginalSequence = null; } myStringRef = null; }
public int copyTo(@Nullable char[] buffer, int start) { CharSequence text = myText(); if (text == null) return -1; if (buffer != null) { CharArrayUtil.getChars(text, buffer, start); } return start + text.length(); }
@NotNull private static String createSequence(@NotNull CharSequence text, int startOffset, int endOffset) { if (text instanceof String) { return ((String) text).substring(startOffset, endOffset); } char[] buf = new char[endOffset - startOffset]; CharArrayUtil.getChars(text, buf, startOffset, 0, buf.length); return StringFactory.createShared( buf); // this way the .toString() doesn't create another instance (as opposed to new // CharArrayCharSequence()) }
private void doInsert(final CharSequence s, final int startIndex) { prepareForModification(); if (isDeferredChangeMode()) { storeChange(new TextChangeImpl(s, startIndex)); if (myDebugDeferredProcessing) { myDebugArray.doInsert(s, startIndex); } return; } int insertLength = s.length(); myArray = relocateArray(myArray, myCount + insertLength); if (startIndex < myCount) { System.arraycopy( myArray, startIndex, myArray, startIndex + insertLength, myCount - startIndex); } CharArrayUtil.getChars(s, myArray, startIndex); myCount += insertLength; }
private void doReplace(int startOffset, int endOffset, CharSequence newString) { prepareForModification(); if (isDeferredChangeMode()) { storeChange(new TextChangeImpl(newString, startOffset, endOffset)); if (myDebugDeferredProcessing) { myDebugArray.doReplace(startOffset, endOffset, newString); } return; } int newLength = newString.length(); int oldLength = endOffset - startOffset; CharArrayUtil.getChars(newString, myArray, startOffset, Math.min(newLength, oldLength)); if (newLength > oldLength) { doInsert(newString.subSequence(oldLength, newLength), endOffset); } else if (newLength < oldLength) { doRemove(startOffset + newLength, startOffset + oldLength); } }
@Override public void getChars(final char[] dst, final int dstOffset) { flushDeferredChanged(myDeferredChangesStorage.get()); if (myOriginalSequence != null) { CharArrayUtil.getChars(myOriginalSequence, dst, dstOffset); } else { System.arraycopy(myArray, myStart, dst, dstOffset, length()); } if (myDebugDeferredProcessing && isDeferredChangeMode()) { char[] expected = new char[dst.length]; myDebugArray.getChars(expected, dstOffset); for (int i = dstOffset, j = myStart; i < dst.length && j < myArray.length; i++, j++) { if (expected[i] != myArray[j]) { dumpDebugInfo( String.format( "getChars(char[], int). Given array of length %d, offset %d. Found char '%c' at index %d, " + "expected to find '%c'", dst.length, dstOffset, myArray[j], i, expected[i])); break; } } } }
/** * Allows to build substring of the client text with its changes registered within the current * storage. * * @param originalData original text to which {@link #myChanges registered changes} are applied * @param start target substring start offset (against the 'client text'; inclusive) * @param end target substring end offset (against the 'client text'; exclusive) * @return substring for the given text range */ public CharSequence substring(@NotNull char[] originalData, int start, int end) { if (myChanges.isEmpty()) { return new String(originalData, start, end - start); } if (end == start) { return ""; } int startChangeIndex = getChangeIndex(start); int endChangeIndex = getChangeIndex(end); boolean substringAffectedByChanges = startChangeIndex >= 0 || endChangeIndex >= 0 || startChangeIndex != endChangeIndex; int clientShift = 0; int originalStart = 0; if (startChangeIndex < 0) { startChangeIndex = -startChangeIndex - 1; if (startChangeIndex > 0 && startChangeIndex <= myChanges.size()) { ChangeEntry changeEntry = myChanges.get(startChangeIndex - 1); clientShift = changeEntry.clientStartOffset - changeEntry.change.getStart() + changeEntry.change.getDiff(); originalStart = changeEntry.change.getEnd(); } } else { ChangeEntry changeEntry = myChanges.get(startChangeIndex); clientShift = changeEntry.clientStartOffset - changeEntry.change.getStart(); } if (!substringAffectedByChanges) { return new String(originalData, start - clientShift, end - start); } char[] data = new char[end - start]; int outputOffset = 0; for (int i = startChangeIndex; i < myChanges.size() && outputOffset < data.length; i++) { ChangeEntry changeEntry = myChanges.get(i); int clientStart = changeEntry.clientStartOffset; if (clientStart >= end) { if (i == startChangeIndex) { return new String(originalData, start - clientShift, end - start); } System.arraycopy( originalData, originalStart, data, outputOffset, data.length - outputOffset); break; } int clientEnd = clientStart + changeEntry.change.getText().length(); if (clientEnd > start) { if (clientStart > start) { int length = Math.min(clientStart - start, changeEntry.change.getStart() - originalStart); length = Math.min(length, data.length - outputOffset); System.arraycopy( originalData, changeEntry.change.getStart() - length, data, outputOffset, length); outputOffset += length; if (outputOffset >= data.length) { break; } } if (end >= clientStart && clientStart < clientEnd) { int changeTextStartOffset = start <= clientStart ? 0 : start - clientStart; int length = Math.min(clientEnd, end) - Math.max(clientStart, start); CharArrayUtil.getChars( changeEntry.change.getText(), data, changeTextStartOffset, outputOffset, length); outputOffset += length; } } originalStart = changeEntry.change.getEnd(); } if (outputOffset < data.length) { System.arraycopy(originalData, originalStart, data, outputOffset, data.length - outputOffset); } return new String(data); }