/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.api.editor.partition; import java.util.List; import com.google.gwt.regexp.shared.MatchResult; import com.google.gwt.regexp.shared.RegExp; /** * Implementation of {@link CharacterScanner} with a String as input. */ public class StringCharacterScanner implements CharacterScanner { /** The scanned content. */ private String content; /** The offset of the scanner within the content. */ private int offset = 0; /** The delimiters of the document. */ private List<String> delimiters; @Override public List<String> getLegalLineDelimiters() { return this.delimiters; } @Override public int getColumn() { return getColumn(this.offset); } private int getColumn(int offset) { // Bad and slow implementation if (offset < 0 || offset > this.content.length()) { return -1; } if (this.delimiters == null || this.delimiters.isEmpty()) { return offset; } final StringBuilder sb = new StringBuilder("["); for (final String delimiter: this.delimiters) { sb.append("(?:") .append(delimiter) .append(")"); } sb.append("]"); final RegExp regexp = RegExp.compile(sb.toString()); final String split = this.content; int currentIndex = 0; while (currentIndex < offset) { final MatchResult matchResult = regexp.exec(split); final int found = matchResult.getIndex(); if (found < 0) { throw new RuntimeException("Invalid index for regexp match"); } if (currentIndex + found > offset) { // we're on the same line as offset return offset - currentIndex; } currentIndex = currentIndex + found + 1; } return -1; } @Override public int read() { if (this.offset == this.content.length()) { return EOF; } final int result = this.content.charAt(this.offset); this.offset++; return result; } @Override public void unread() { if (this.offset != 0) { this.offset--; }// else already at doc start } public void setLegalLineDelimiters(final List<String> delimiters) { this.delimiters = delimiters; } public void setScannedString(final String content) { this.content = content; this.offset = 0; } }