@Override public void skip(int distance) { assert cursor != -1; assert distance > 0; if (distance > size() - cursor) { throw new OpCursorException("Attempt to skip beyond end of document (cursor at " + cursor + ", size is " + size() + ", distance is " + distance + ")"); } cursor += distance; assert cursor > 0; updateInheritedAnnotationsFromPosition(cursor - 1); }
@Override public void delete(int deleteSize) { assert cursor != -1; assert deleteSize > 0; if (deleteSize > size() - cursor) { throw new OpCursorException("Attempt to delete beyond end of document (cursor at " + cursor + ", size is " + size() + ", deleteSize is " + deleteSize + ")"); } updateInheritedAnnotationsFromPosition(cursor + deleteSize - 1); tree.delete(cursor, cursor + deleteSize); }
@Override public AnnotationCursor annotationCursor(int start, int end, ReadableStringSet keys) { Preconditions.checkPositionIndexes(start, end, size()); if (keys == null) { //return tree.allAnnotationsCursor(start, end); throw new RuntimeException("Not supported"); } else { return new GenericAnnotationCursor<V>(this, start, end, keys); } }
@Override public void forEachAnnotationAt(int index, ReadableStringMap.ProcV<V> callback) { Preconditions.checkElementIndex(index, size()); tree.forEachAnnotationAt(index, callback); }
@Override public Iterable<RangedAnnotation<V>> rangedAnnotations(int start, int end, ReadableStringSet keys) { Preconditions.checkPositionIndexes(start, end, size()); if (keys == null) { keys = tree.knownKeys(); } return new GenericRangedAnnotationIterable<V>(this, start, end, keys); }
@Override public int lastAnnotationChange(int start, int end, String key, V fromValue) { Preconditions.checkPositionIndexes(start, end, size()); checkKeyNotNull(key); return tree.lastAnnotationChange(start, end, key, fromValue); }
@Override public V getAnnotation(int location, String key) { Preconditions.checkElementIndex(location, size()); checkKeyNotNull(key); return tree.getAnnotation(location, key); }
@Override public int firstAnnotationChange(int start, int end, String key, V fromValue) { Preconditions.checkPositionIndexes(start, end, size()); checkKeyNotNull(key); return tree.firstAnnotationChange(start, end, key, fromValue); }
/** * For simplicity of implementation, this implementation doesn't * guarantee that the start of the first interval is minimal. I.e., it * may be that the item to the left of start() of the first interval returned * actually has the same annotations. */ @Override public Iterable<AnnotationInterval<V>> annotationIntervals(int start, int end, ReadableStringSet keys) { Preconditions.checkPositionIndexes(start, end, size()); if (keys == null || tree.knownKeys().isSubsetOf(keys)) { // TODO(ohler): Implement this more efficiently with support // from the underlying data structure. return new GenericAnnotationIntervalIterable<V>(this, start, end, tree.knownKeys()); } else { return new GenericAnnotationIntervalIterable<V>(this, start, end, keys); } }