/******************************************************************************
* Copyright (C) 2015 Fabio Zadrozny and others
*
* 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:
* Fabio Zadrozny <fabiofz@gmail.com> - initial API and implementation
******************************************************************************/
package org.python.pydev.shared_core.string;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.python.pydev.shared_core.structure.FastStack;
public class StringScanner implements ICharacterScanner {
private final String contents;
private int offset;
private final int length;
public StringScanner(String contents) {
this.contents = contents;
this.length = contents.length();
}
@Override
public int read() {
if (offset < length) {
// Most common case first.
char ret = contents.charAt(offset);
offset += 1;
return ret;
}
if (offset == length) {
offset++;
return StringScanner.EOF; //EOF
}
// offset > length!
throw new RuntimeException("Reading past EOF!");
}
// peek(0) reads the char at the current offset, peek(-1) reads the previous, peek(1) reads the next
// and so on (all without changing the current offset).
public int peek(int i) {
int checkAt = offset + i;
if (checkAt >= length || checkAt < 0) {
return StringScanner.EOF;
}
return contents.charAt(checkAt);
}
@Override
public void unread() {
offset -= 1;
if (offset < 0) {
throw new RuntimeException("Reading before begin of stream.");
}
}
public int getMark() {
return offset;
}
public String getContents() {
return this.contents;
}
final FastStack<char[]> endLevel = new FastStack<>(3);
public void addLevelFinishingAt(char... endLevelChar) {
endLevel.push(endLevelChar);
}
public void popLevel() {
endLevel.pop();
}
public void setMark(int mark) {
this.offset = mark;
}
public boolean isEndLevelChar(int c) {
if (!endLevel.isEmpty()) {
char[] peek = endLevel.peek();
int len = peek.length;
for (int i = 0; i < len; i++) {
if (peek[i] == c) {
return true;
}
}
}
return false;
}
public int getLevel() {
return endLevel.size();
}
@Override
public char[][] getLegalLineDelimiters() {
throw new AssertionError("Not implemented");
}
@Override
public int getColumn() {
throw new AssertionError("Not implemented");
}
}