private void finalizeMods() { if (replacedSequence == null) { replacedSequence = SegmentedSequence.of(replacedSegments); } }
@Override public BasedSequence subSequence(int start, int end) { if (start < 0 || start > length) { throw new StringIndexOutOfBoundsException("String index out of range: " + start); } if (end < 0 || end > length) { throw new StringIndexOutOfBoundsException("String index out of range: " + end); } if (start == 0 && end == length) { return this; } else { return new SegmentedSequence(baseSeq, baseOffsets, baseStartOffset + start, nonBaseChars, end - start); } }
private SegmentedSequence(BasedSequence baseSeq, int[] baseOffsets, int baseStartOffset, char[] nonBaseChars, int length) { this.baseSeq = baseSeq; this.baseOffsets = baseOffsets; this.baseStartOffset = baseStartOffset; this.nonBaseChars = nonBaseChars; this.length = length; this.startOffset = computeStartOffset(); this.endOffset = computeEndOffset(); }
@Override public Range getSourceRange() { return new Range(getStartOffset(), getEndOffset()); }
private int computeEndOffset() { // ensure that 0 length end returns start if (length == 0) return getStartOffset(); int iMax = baseOffsets.length; if (nonBaseChars != null) { // end is the last real end in this sequence for (int i = baseStartOffset + length; i-- > 0; ) { if (baseOffsets[i] >= 0) return baseOffsets[i] + 1; } // failing that it is the same as startOffset return getStartOffset(); } // here there are no nonBaseChars, all sequences are based sequences return baseOffsets[baseStartOffset + length - 1] + 1; }
@Override public Range getSourceRange() { return new Range(getStartOffset(), getEndOffset()); }
private int computeEndOffset() { // ensure that 0 length end returns start if (length == 0) return getStartOffset(); int iMax = baseOffsets.length; if (nonBaseChars != null) { // end is the last real end in this sequence for (int i = baseStartOffset + length; i-- > 0; ) { if (baseOffsets[i] >= 0) return baseOffsets[i] + 1; } // failing that it is the same as startOffset return getStartOffset(); } // here there are no nonBaseChars, all sequences are based sequences return baseOffsets[baseStartOffset + length - 1] + 1; }
@Override public BasedSequence getContentChars() { return SegmentedSequence.of(lineSegments); }
private SegmentedSequence(BasedSequence baseSeq, int[] baseOffsets, int baseStartOffset, char[] nonBaseChars, int length) { this.baseSeq = baseSeq; this.baseOffsets = baseOffsets; this.baseStartOffset = baseStartOffset; this.nonBaseChars = nonBaseChars; this.length = length; this.startOffset = computeStartOffset(); this.endOffset = computeEndOffset(); }
return mergedSequences.get(0); } else if (mergedSequences.size() != 0) { return new SegmentedSequence(mergedSequences, startOffset, endOffset);
public BasedSequence toBasedSequence() { return SegmentedSequence.of(segments); }
@Override public BasedSequence subSequence(int start, int end) { if (start < 0 || start > length) { throw new StringIndexOutOfBoundsException("String index out of range: " + start); } if (end < 0 || end > length) { throw new StringIndexOutOfBoundsException("String index out of range: " + end); } if (start == 0 && end == length) { return this; } else { return new SegmentedSequence(baseSeq, baseOffsets, baseStartOffset + start, nonBaseChars, end - start); } }
public static BasedSequence of(BasedSequence... segments) { return of(Arrays.asList(segments)); } }
return mergedSequences.get(0); } else if (mergedSequences.size() != 0) { return new SegmentedSequence(mergedSequences, startOffset, endOffset);
/** * Get the char sequence from segments making up the node's characters. * <p> * Used to get segments after the some of the node's elements were modified * * @return concatenated string of all segments */ public BasedSequence getCharsFromSegments() { return SegmentedSequence.of(Arrays.asList(getSegmentsForChars())); }
public BasedSequence getContents(int startLine, int endLine) { if (lines.size() == 0) return BasedSequence.NULL; if (startLine < 0) { throw new IndexOutOfBoundsException("startLine must be at least 0"); } if (endLine < 0) { throw new IndexOutOfBoundsException("endLine must be at least 0"); } if (endLine < startLine) { throw new IndexOutOfBoundsException("endLine must not be less than startLine"); } if (endLine > lines.size()) { throw new IndexOutOfBoundsException("endLine must not be greater than line cardinality"); } return SegmentedSequence.of(lines.subList(startLine, endLine)); }
@Override public BasedSequence getContentChars(int startLine, int endLine) { return SegmentedSequence.of(getContentLines(startLine, endLine)); }
@Override public boolean flushTextNode() { if (currentText != null) { block.appendChild(new Text(SegmentedSequence.of(currentText))); currentText = null; return true; } return false; }
public static BasedSequence stripIndent(BasedSequence input, CharSequence sourceIndent) { BasedSequence result = input; if (sourceIndent.length() != 0) { // strip out indent to test how segmented input parses ArrayList<BasedSequence> segments = new ArrayList<>(); int lastPos = 0; int length = input.length(); while (lastPos < length) { int pos = input.indexOf(sourceIndent, lastPos); int end = pos == -1 ? length : pos; if (lastPos < end && (pos <= 0 || input.charAt(pos - 1) == '\n')) { segments.add(input.subSequence(lastPos, end)); } lastPos = end + sourceIndent.length(); } result = SegmentedSequence.of(segments); } return result; }
@Override public void mergeIfNeeded(Text first, Text last) { if (first != null && last != null && first != last) { ArrayList<BasedSequence> sb = new ArrayList<BasedSequence>(); sb.add(first.getChars()); Node node = first.getNext(); Node stop = last.getNext(); while (node != stop) { sb.add(node.getChars()); Node unlink = node; node = node.getNext(); unlink.unlink(); } BasedSequence literal = SegmentedSequence.of(sb); first.setChars(literal); } }