/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.parser; /** * Class to provide character-based access to an input source string */ final class TokenStreamInput { /** * The end-of-file marker */ public static final int EOF = -1; private final String source; private final int length; private int cursor = 0; public TokenStreamInput(String source) { this.source = source; this.length = source.length(); } /** * Returns the input length. * * @return the input length */ public int length() { return length; } /** * Returns the current code point or {@link TokenStreamInput#EOF} when the end of the input has * been reached. * * @return the current code point or {@link TokenStreamInput#EOF} */ public int get() { if (cursor >= length) return EOF; int cp = source.codePointAt(cursor); cursor += Character.charCount(cp); return cp; } /** * Returns the current character or {@link TokenStreamInput#EOF} when the end of the input has * been reached. * * @return the current character or {@link TokenStreamInput#EOF} */ public int getChar() { if (cursor >= length) return EOF; return source.charAt(cursor++); } /** * Returns the last character. * * @return the last character */ public int lastChar() { assert cursor > 0 : cursor; return source.charAt(cursor - 1); } /** * Ungets the code point {@code c}. * * @param c * the code point to read back */ public void unget(int c) { assert c != EOF ? source.codePointAt(cursor - Character.charCount(c)) == c : cursor >= length; if (c != EOF) cursor -= Character.charCount(c); } /** * Ungets the character {@code c}. * * @param c * the character to read back */ public void ungetChar(int c) { assert c != EOF ? source.charAt(cursor - 1) == c : cursor >= length; if (c != EOF) cursor -= 1; } /** * Advances the position if the current character is equal to {@code c}. * * @param c * the current to test * @return {@code true} if the current character matches */ public boolean match(char c) { if (cursor >= length || source.charAt(cursor) != c) return false; cursor += 1; return true; } /** * Returns the character at {@code position() + offset} without changing the actual position. * * @param offset * the source position offset * @return the character at {@code position() + offset} or {@link TokenStreamInput#EOF} */ public int peek(int offset) { assert offset >= 0; if (cursor + offset >= length) return EOF; return source.charAt(cursor + offset); } /** * Returns the current position in the input. * * @return the current position */ public int position() { return cursor; } /** * Resets the position to {@code position}. * * @param position * the new position */ public void reset(int position) { assert position >= 0 && position <= cursor; cursor = position; } /** * Returns the source characters from position {@code from} to position {@code to} (exclusive). * * @param from * the start position (inclusive) * @param to * the end position (exclusive) * @return the source characters in the given range */ public String range(int from, int to) { return source.substring(from, to); } /** * Copies the source characters from position {@code from} to position {@code to} (exclusive). * * @param from * the start position (inclusive) * @param to * the end position (exclusive) * @param array * the destination array * @param offset * the start offset in the array */ public void chars(int from, int to, char[] array, int offset) { source.getChars(from, to, array, offset); } }