com.yahoo.text.PositionedString Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.text;
/**
* A string which has a current position.
* Useful for writing simple single-pass parsers.
*
* @author bratseth
*/
public class PositionedString {
private final String s;
private int p;
/**
* Creates this from a given string.
*/
public PositionedString(String string) {
this.s=string;
}
/** The complete string value of this */
public String string() { return s; }
/** The current position into this string */
public int position() { return p; }
/** Assigns the current position in the string */
public void setPosition(int position) { p=position; }
/**
* Consumes the character at this position.
*
Precondition: The character at this position is c.
*
Postcondition: The position is increased by 1
*
* @param c the expected character at this
* @throws IllegalArgumentException if the character at this position is not c
*/
public void consume(char c) {
if (s.charAt(p++)!=c)
throw new IllegalArgumentException("Expected '" + c + "' " + at(p -1));
}
/**
* Consumes zero or more whitespace characters starting at the current position
*/
public void consumeSpaces() {
while (Character.isWhitespace(s.charAt(p)))
p++;
}
/**
* Advances the position by 1 if the character at the current position is c.
* Does nothing otherwise.
*
* @return whether this consumed a c at the current position, or if it did nothing
*/
public boolean consumeOptional(char c) {
if (s.charAt(p)!=c) return false;
p++;
return true;
}
/**
* Returns whether the character at the current position is c.
*/
public boolean peek(char c) {
return s.charAt(p)==c;
}
/**
* Returns the position of the next occurrence of c,
* or -1 if there are no occurrences of c in the string after the current position.
*/
public int indexOf(char c) {
return s.indexOf(c,p);
}
/** Adds n to the current position */
public void skip(int n) {
p = p +n;
}
/**
* Sets the position of this to the next occurrence of c after the current position.
*
* @param c the char to move the position to
* @return the substring between the current position and the new position at c
* @throws IllegalArgumentException if there was no occurrence of c after the current position
*/
public String consumeTo(char c) {
int nextC=indexOf(c);
if (nextC<0)
throw new IllegalArgumentException("Expected a string terminated by '" + c + "' " + at());
String value=substring(nextC);
p=nextC;
return value;
}
/**
* Returns the substring between the current position and position
* and advances the current position to position
*/
public String consumeToPosition(int position) {
String consumed=substring(position);
p=position;
return consumed;
}
/** Returns a substring of this from the current position to the end argument */
public String substring(int end) {
return string().substring(position(),end);
}
/** Returns the substring of this string from the current position to the end */
public String substring() {
return string().substring(position());
}
/** Returns a textual description of the current position, useful for appending to error messages. */
public String at() {
return at(p);
}
/** Returns a textual description of a given position, useful for appending to error messages. */
public String at(int position) {
return "starting at position " + position + " but was '" + s.charAt(position) + "'";
}
/** Returns the string */
@Override
public String toString() {
return s;
}
}