Class StringReader

java.lang.Object
net.luis.utils.io.reader.StringReader
Direct Known Subclasses:
ScopedStringReader

public class StringReader extends Object
Represents a reader to read from a string.
The reader can read specific types of values from the string such as:
  • Quoted and unquoted strings
  • Booleans
  • Numbers (byte, short, integer, long, float, double)
  • Big numbers (BigInteger, BigDecimal)

This reader implementation is not performance optimized,
it reads the string character by character in O(n).

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static final record 
    Internal to represent a parsed number.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private int
    The current index of the reader.
    private int
    The marked index of the reader.
    private final String
    The string to read from.
  • Constructor Summary

    Constructors
    Constructor
    Description
    StringReader(@NotNull Reader reader)
    Constructs a new string reader from the given reader.
    The reader is closed after reading the string.
    StringReader(@NotNull String string)
    Constructs a new string reader with the given string.
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    Checks whether there are more characters to read.
    boolean
    canRead(int amount)
    Checks whether there is at least the given number of characters to read.
    boolean
    canRead(int amount, @NotNull Predicate<Character> predicate)
    Checks whether the number of characters to read matches the given predicate.
    boolean
     
    int
    Returns the current character index of the reader.
    @NotNull String
    Returns the string to read from.
    int
     
    void
    Marks the current index of the reader.
    The marked index can be reset to by calling reset().
    After calling reset(), the marked index will be reset.
    char
    Peeks the current character without incrementing the index.
    char
    Reads the next character from the string.
    @NotNull String
    read(int amount)
    Reads the given number of characters from the string.
    @NotNull BigDecimal
    Reads a big decimal.
    @NotNull BigInteger
    Reads a big integer.
    boolean
    Reads a boolean.
    The boolean is read as an unquoted string and then parsed case-insensitive.
    byte
    Reads a byte.
    The number can be suffixed with a b (case-insensitive) to indicate that it is a byte.
    double
    Reads a double.
    The number can be suffixed with a d (case-insensitive) to indicate that it is a double.
    @NotNull String
    readExpected(@NotNull String expected, boolean caseSensitive)
    Reads the given expected string from the reader.
    If any read character does not match the expected character, an exception is thrown.
    @NotNull String
    readExpected(@NotNull List<String> expected, boolean caseSensitive)
    Reads the first matching expected string from the reader.
    float
    Reads a float.
    The number can be suffixed with an f (case-insensitive) to indicate that it is a float.
    int
    Reads an integer.
    The number can be suffixed with an i (case-insensitive) to indicate that it is an integer.
    @NotNull String
    readLine(boolean includeLineBreak)
    Reads all characters until the next line break is found.
    Supported line breaks are: LF ('\n'), CR ('\r'), CRLF ('\r\n').
    long
    Reads a long.
    The number can be suffixed with an l (case-insensitive) to indicate that it is a long.
    @NotNull Number
    Reads a number.
    If the number is specified with a type suffix, the number is parsed as the specified type.
    By default, the number is parsed as a double if it contains a dot otherwise as a long.
    private @Nullable StringReader.ParsedNumber
    readNumberAsString(@Nullable NumberType initialType)
    Reads a number as a string of the given type.
    The initial type is used to determine the type of the number,
    it can be overridden by a larger number type (e.g.
    @NotNull String
    Reads a quoted string.
    A quoted string is a string enclosed in single or double quotes.
    The quotes are read but not included in the result.
    @NotNull String
    Reads the remaining string.
    short
    Reads a short.
    The number can be suffixed with an s (case-insensitive) to indicate that it is a short.
    @NotNull String
    Reads a string.
    @NotNull String
    Reads the string until the next whitespace (' ') is found.
    The whitespace is read but not included in the result.
    @NotNull String
    readUnquotedString(char terminator)
    Reads the string until the given terminator is found.
    The string will be read in 'raw' mode, meaning that no escaping is done.
    The terminator is read but not included in the result.
    @NotNull String
    readUntil(char terminator)
    Reads the string until the given terminator is found.
    The terminator and escape character ('\\') are read but not included in the result.
    @NotNull String
    readUntil(char @NotNull ... terminators)
    Reads the string until any of the given terminators is found.
    The terminators and escape character ('\\') are read but not included in the result.
    @NotNull String
    readUntil(@NotNull String terminator, boolean caseSensitive)
    Reads the string until the given terminator string is found.
    The terminator string and escape character ('\\') are read but not included in the result.
    protected @NotNull String
    readUntil(@NotNull String terminator, boolean caseSensitive, boolean inclusive)
    Internal method to read the string until the terminating string is found.
    protected @NotNull String
    readUntil(@NotNull Predicate<Character> predicate, boolean inclusive)
    Internal method to read the string until the given predicate is true.
    @NotNull String
    readUntilInclusive(char terminator)
    Reads the string until the given terminator is found.
    The escape character ('\\') is read but not included in the result.
    @NotNull String
    readUntilInclusive(char... terminators)
    Reads the string until any of the given terminators is found.
    The escape character ('\\') is read but not included in the result.
    @NotNull String
    readUntilInclusive(@NotNull String terminator, boolean caseSensitive)
    Reads the string until the given terminator string is found.
    The escape character ('\\') is read but not included in the result.
    void
    Resets the index of the reader to zero or if set to the marked index.
    If the marked index is set, it will be reset after calling this method.
    void
    Skips the next character.
    Increments the index by one.
    void
    skip(char c)
    Skips all characters that are equal to the given character.
    If the next character is not equal to the given character
    or there are no more characters to read, nothing happens.
    void
    skip(int amount)
    Skips the given number of characters.
    void
    skip(@NotNull Predicate<Character> predicate)
    Skips all characters that match the given predicate.
    If the next character does not match the predicate
    or there are no more characters to read, nothing happens.
    void
    Skips all whitespaces.
    A whitespace is a character that returns true when calling Character.isWhitespace(char).

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • string

      private final String string
      The string to read from.
    • index

      private int index
      The current index of the reader.
    • markedIndex

      private int markedIndex
      The marked index of the reader.
  • Constructor Details

    • StringReader

      public StringReader(@NotNull @NotNull String string)
      Constructs a new string reader with the given string.
      Parameters:
      string - The string to read from
      Throws:
      NullPointerException - If the string is null
    • StringReader

      public StringReader(@NotNull @NotNull Reader reader)
      Constructs a new string reader from the given reader.
      The reader is closed after reading the string.
      Parameters:
      reader - The reader to read from
      Throws:
      NullPointerException - If the reader is null
      UncheckedIOException - If an I/O error occurs while reading the string
  • Method Details

    • getString

      @NotNull public @NotNull String getString()
      Returns the string to read from.
      Returns:
      The string
    • getIndex

      public int getIndex()
      Returns the current character index of the reader.
      Returns:
      The current index
    • read

      public char read()
      Reads the next character from the string.
      Returns:
      The next character
      Throws:
      IndexOutOfBoundsException - If there are no more characters to read (canRead() returns false)
    • read

      @NotNull public @NotNull String read(int amount)
      Reads the given number of characters from the string.
      Parameters:
      amount - The number of characters to read
      Returns:
      The read characters as a string
      Throws:
      IllegalArgumentException - If the amount is less than or equal to zero
      IndexOutOfBoundsException - If there are not enough characters to read (canRead(int) returns false)
    • canRead

      public boolean canRead(int amount)
      Checks whether there is at least the given number of characters to read.
      Parameters:
      amount - The number of characters to read
      Returns:
      True if there is at least a given number of characters to read, otherwise false
      Throws:
      IllegalArgumentException - If the amount is less than or equal to zero
    • canRead

      public boolean canRead()
      Checks whether there are more characters to read.
      Returns:
      True if there are more characters to read, otherwise false
    • canRead

      public boolean canRead(int amount, @NotNull @NotNull Predicate<Character> predicate)
      Checks whether the number of characters to read matches the given predicate.
      Parameters:
      amount - The number of characters to read
      predicate - The predicate to match the characters
      Returns:
      True if the number of characters to read matches the predicate, otherwise false
    • peek

      public char peek()
      Peeks the current character without incrementing the index.
      Returns:
      The current character
    • skip

      public void skip()
      Skips the next character.
      Increments the index by one.
    • skip

      public void skip(int amount)
      Skips the given number of characters.
      Parameters:
      amount - The number of characters to skip
      Throws:
      IllegalArgumentException - If the amount is less than or equal to zero
    • skip

      public void skip(char c)
      Skips all characters that are equal to the given character.
      If the next character is not equal to the given character
      or there are no more characters to read, nothing happens.
      Parameters:
      c - The character to skip
    • skip

      public void skip(@NotNull @NotNull Predicate<Character> predicate)
      Skips all characters that match the given predicate.
      If the next character does not match the predicate
      or there are no more characters to read, nothing happens.
      Parameters:
      predicate - The predicate to match
      Throws:
      NullPointerException - If the predicate is null
    • skipWhitespaces

      public void skipWhitespaces()
      Skips all whitespaces.
      A whitespace is a character that returns true when calling Character.isWhitespace(char).
    • mark

      public void mark()
      Marks the current index of the reader.
      The marked index can be reset to by calling reset().
      After calling reset(), the marked index will be reset.
    • reset

      public void reset()
      Resets the index of the reader to zero or if set to the marked index.
      If the marked index is set, it will be reset after calling this method.
    • readLine

      @NotNull public @NotNull String readLine(boolean includeLineBreak)
      Reads all characters until the next line break is found.
      Supported line breaks are: LF ('\n'), CR ('\r'), CRLF ('\r\n').
      Parameters:
      includeLineBreak - Whether the line break should be included in the result or not
      Returns:
      The line which was read
    • readRemaining

      @NotNull public @NotNull String readRemaining()
      Reads the remaining string.
      Returns:
      The remaining string
    • readUnquotedString

      @NotNull public @NotNull String readUnquotedString()
      Reads the string until the next whitespace (' ') is found.
      The whitespace is read but not included in the result.
      Returns:
      The string read until the default terminator
      See Also:
    • readUnquotedString

      @NotNull public @NotNull String readUnquotedString(char terminator)
      Reads the string until the given terminator is found.
      The string will be read in 'raw' mode, meaning that no escaping is done.
      The terminator is read but not included in the result.
      Parameters:
      terminator - The terminator to read until
      Returns:
      The string which was read until the terminator
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
    • readQuotedString

      @NotNull public @NotNull String readQuotedString()
      Reads a quoted string.
      A quoted string is a string enclosed in single or double quotes.
      The quotes are read but not included in the result.
      Returns:
      The quoted string which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the next read character is not a single or double quote
    • readString

      @NotNull public @NotNull String readString()
      Reads a string.

      If the next character is a single or double quote,
      readQuotedString() is called otherwise readUnquotedString() is called.
      If there are no more characters to read, an empty string is returned.

      Returns:
      The string which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      See Also:
    • readUntil

      @NotNull public @NotNull String readUntil(char terminator)
      Reads the string until the given terminator is found.
      The terminator and escape character ('\\') are read but not included in the result.

      If the terminator is found at the beginning or at the end of the string, an empty string is returned.
      If the terminator is found in a quoted part of the string, the terminator is ignored.
      If the terminator is not found, the rest of the string is returned.

      Parameters:
      terminator - The terminator to read until
      Returns:
      The string which was read until the terminator
      Throws:
      IllegalArgumentException - If the terminator is a backslash
    • readUntilInclusive

      @NotNull public @NotNull String readUntilInclusive(char terminator)
      Reads the string until the given terminator is found.
      The escape character ('\\') is read but not included in the result.

      If the terminator is found at the beginning or at the end of the string, an empty string is returned.
      If the terminator is found in a quoted part of the string, the terminator is ignored.
      If the terminator is not found, the rest of the string is returned.

      Parameters:
      terminator - The terminator to read until
      Returns:
      The string which was read until the terminator
      Throws:
      IllegalArgumentException - If the terminator is a backslash
    • readUntil

      @NotNull public @NotNull String readUntil(char @NotNull ... terminators)
      Reads the string until any of the given terminators is found.
      The terminators and escape character ('\\') are read but not included in the result.

      If any terminator is found at the beginning or at the end of the string, an empty string is returned.
      If any terminator is found in a quoted part of the string, the terminator is ignored.
      If none terminator is found, the rest of the string is returned.

      Parameters:
      terminators - The terminators to read until
      Returns:
      The string which was read until the terminator
      Throws:
      IllegalArgumentException - If the terminators are empty or contain a backslash
    • readUntilInclusive

      @NotNull public @NotNull String readUntilInclusive(char... terminators)
      Reads the string until any of the given terminators is found.
      The escape character ('\\') is read but not included in the result.

      If any terminator is found at the beginning or at the end of the string, an empty string is returned.
      If any terminator is found in a quoted part of the string, the terminator is ignored.
      If none terminator is found, the rest of the string is returned.

      Parameters:
      terminators - The terminators to read until
      Returns:
      The string which was read until the terminator
      Throws:
      IllegalArgumentException - If the terminators are empty or contain a backslash
    • readUntil

      @Internal @NotNull protected @NotNull String readUntil(@NotNull @NotNull Predicate<Character> predicate, boolean inclusive)
      Internal method to read the string until the given predicate is true.
      Parameters:
      predicate - The predicate to match the characters
      inclusive - Whether the character which matches the predicate should be included in the result or not
      Returns:
      The string which was read until the predicate is true
      See Also:
    • readUntil

      @NotNull public @NotNull String readUntil(@NotNull @NotNull String terminator, boolean caseSensitive)
      Reads the string until the given terminator string is found.
      The terminator string and escape character ('\\') are read but not included in the result.

      If the terminator string is found at the beginning or at the end of the string, an empty string is returned.
      If the terminator string is found in a quoted part of the string, the terminator is ignored.
      If the terminator string is not found, the rest of the string is returned.

      Parameters:
      terminator - The terminating string to read until
      caseSensitive - Whether the terminator string should be case-sensitive or not
      Returns:
      The string which was read until the terminator
      Throws:
      NullPointerException - If the terminator string is null
      IllegalArgumentException - If the terminator string is empty or contains a backslash
    • readUntilInclusive

      @NotNull public @NotNull String readUntilInclusive(@NotNull @NotNull String terminator, boolean caseSensitive)
      Reads the string until the given terminator string is found.
      The escape character ('\\') is read but not included in the result.

      If the terminator string is found at the beginning or at the end of the string, an empty string is returned.
      If the terminator string is found in a quoted part of the string, the terminator is ignored.
      If the terminator string is not found, the rest of the string is returned.

      Parameters:
      terminator - The terminating string to read until
      caseSensitive - Whether the terminator string should be case-sensitive or not
      Returns:
      The string which was read until the terminator
      Throws:
      NullPointerException - If the terminator string is null
      IllegalArgumentException - If the terminator string is empty or contains a backslash
    • readUntil

      @Internal @NotNull protected @NotNull String readUntil(@NotNull @NotNull String terminator, boolean caseSensitive, boolean inclusive)
      Internal method to read the string until the terminating string is found.
      Parameters:
      terminator - The terminator string to read until
      caseSensitive - Whether the terminator string should be case-sensitive or not
      inclusive - Whether the terminator string should be included in the result or not
      Returns:
      The string which was read until the equals predicate is true
      Throws:
      NullPointerException - If the terminator string is null
      See Also:
    • readExpected

      @NotNull public @NotNull String readExpected(@NotNull @NotNull String expected, boolean caseSensitive)
      Reads the given expected string from the reader.
      If any read character does not match the expected character, an exception is thrown.

      If the expected string could not be read, an exception is thrown.
      The reader index is set to the last matching character of the expected string.

      Parameters:
      expected - The expected string
      caseSensitive - Whether the expected string should be case-sensitive or not
      Returns:
      The expected string which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      IllegalArgumentException - If the expected string is empty
      InvalidStringException - If the string read does not match the expected string
    • readExpected

      @NotNull public @NotNull String readExpected(@NotNull @NotNull List<String> expected, boolean caseSensitive)
      Reads the first matching expected string from the reader.

      If any read character does not match the expected character of a given string,
      the string is removed from the list.
      If no expected string matches the read string, an exception is thrown.

      If none of the expected strings could be read, an exception is thrown.
      The reader index is set to the last matching character of the expected strings.

      Parameters:
      expected - The list of expected strings
      caseSensitive - Whether the expected strings should be case-sensitive or not
      Returns:
      The expected string which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      IllegalArgumentException - If the list of expected strings is empty
      InvalidStringException - If the string read does not match any of the expected strings
    • readBoolean

      public boolean readBoolean()
      Reads a boolean.
      The boolean is read as an unquoted string and then parsed case-insensitive.
      Returns:
      The boolean value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a boolean
    • readNumberAsString

      @Nullable private @Nullable StringReader.ParsedNumber readNumberAsString(@Nullable @Nullable NumberType initialType)
      Reads a number as a string of the given type.
      The initial type is used to determine the type of the number,
      it can be overridden by a larger number type (e.g. reading a byte as a long).

      The number can be quoted or unquoted.
      The first character can be a minus or plus sign.
      The number can contain a single dot for float or double values.
      The number can contain a type suffix (single character, case-insensitive) at the end of the number:

      • byte: 'b'
      • short: 's'
      • integer: 'i'
      • long: 'l'
      • float: 'f'
      • double: 'd'

      The number can be specified in:

      • binary by prefixing with '0b'
      • octal by prefixing with a single '0'
      • decimal by default
      • hexadecimal by prefixing with '0x'

      The number can contain underscores to separate digits.
      Floating point numbers can contain an exponent with 'e' or 'p' for hexadecimal floating point numbers.

      Parameters:
      initialType - The initial number type to read as
      Returns:
      The number as a string which was read
      Throws:
      InvalidStringException - If the read value is not a (valid) number
    • readNumber

      @NotNull public @NotNull Number readNumber()
      Reads a number.
      If the number is specified with a type suffix, the number is parsed as the specified type.
      By default, the number is parsed as a double if it contains a dot otherwise as a long.
      Returns:
      The number value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) number
      See Also:
    • readByte

      public byte readByte()
      Reads a byte.
      The number can be suffixed with a b (case-insensitive) to indicate that it is a byte.
      Returns:
      The byte value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) byte
      See Also:
    • readShort

      public short readShort()
      Reads a short.
      The number can be suffixed with an s (case-insensitive) to indicate that it is a short.
      Returns:
      The short value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) short
      See Also:
    • readInt

      public int readInt()
      Reads an integer.
      The number can be suffixed with an i (case-insensitive) to indicate that it is an integer.
      Returns:
      The integer value which was read
      Throws:
      InvalidStringException - If the read value is not a (valid) integer
      See Also:
    • readLong

      public long readLong()
      Reads a long.
      The number can be suffixed with an l (case-insensitive) to indicate that it is a long.
      Returns:
      The long value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) long
      See Also:
    • readFloat

      public float readFloat()
      Reads a float.
      The number can be suffixed with an f (case-insensitive) to indicate that it is a float.
      Returns:
      The float value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) float
      See Also:
    • readDouble

      public double readDouble()
      Reads a double.
      The number can be suffixed with a d (case-insensitive) to indicate that it is a double.
      Returns:
      The double value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) double
      See Also:
    • readBigInteger

      @NotNull public @NotNull BigInteger readBigInteger()
      Reads a big integer.
      Returns:
      The big integer value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) big integer
      See Also:
    • readBigDecimal

      @NotNull public @NotNull BigDecimal readBigDecimal()
      Reads a big decimal.
      Returns:
      The big decimal value which was read
      Throws:
      StringIndexOutOfBoundsException - If there are no more characters to read
      InvalidStringException - If the read value is not a (valid) big decimal
      See Also:
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object