StringReader

StringReader is a subclass of InStream with additional member functions for parsing text.

The InStream and StringReader classes are, in fact, interchangeable. You can cast an InStream to a StringReader at any time by calling InStream::strReader(). The main reason why InStream and StringReader are separate classes is to help express intention in the code. InStreams are mainly intended to read binary data, and StringReaders are mainly intended to read text encoded in an 8-bit format compatible with ASCII, such as UTF-8, ISO 8859-1, Windows-1252 or ASCII itself.

Just like InStream, you can create a StringReader directly from an InPipe, such as stdIn. However, such a StringReader will not perform any automatic newline conversion:

StringReader sr{stdIn};

To create a StringReader directly from a String or a StringView, use StringViewReader instead.

Most StringReader parse functions only recognize characters in the ASCII character set, and will work with text in any 8-bit encoding compatible with ASCII such as UTF-8, ISO 8859-1 or Windows-1252. If you have text encoded as UTF-16, you can create an adapter to convert it to UTF-8 automatically using createImporter().

StringReader itself does not perform any newline conversion. Most StringReader parse functions consider '\r' as whitespace and '\n' as newline. In particular, StringReader::readString<fmt::Line>() always returns a string that ends with '\n' and will preserve '\r' characters unchanged. If you expect Windows-style newlines in your input, and you want them automatically converted to Unix-style newlines, use createImporter() to strip out '\r' characters automatically.

For more information, see Unicode Support.

Header File

#include <ply-runtime/io/text/StringReader.h>

Also included from <ply-runtime/Base.h>.

Member Functions

StringReader() [code]

Constructs an empty StringReader. You can replace it with a valid StringReader later using move assignment.

StringReader(StringReader&& other) [code]

Move constructor.

StringReader(OptionallyOwned<InPipe>&& inPipe, u32 chunkSizeExp = DefaultChunkSizeExp) [code]

Constructs a StringReader from an InPipe. If inPipe is an owned pointer, the StringReader takes ownership of the InPipe and will automatically destroy it in its destructor. If inPipe is a borrowed pointer, the StringReader does not take ownership of the InPipe.

[FIXME: Link to text conversion streams here]

bool anyParseError() const [code]

Returns true if an error occurred in a previously called parse function.

template <typename Type>
Type parse(const decltype(fmt::TypeParser<Type>::defaultFormat())& format = fmt::TypeParser<Type>::defaultFormat()) [code]

A template function to parse the data type given by Type. It currently supports s8, s16, s32, s64, u8, u16, u32, u64, float and double. You can extend it to support additional types by specializing the fmt::TypeParser class template.

u32 a = strReader.parse<u32>();         // parse an integer such as "123"
double b = strReader.parse<double>();   // parse a floating-point number such as "-123.456"

This function accepts an optional argument format whose type depends on the data type being parsed. For s8, s16, s32, s64, u8, u16, u32, u64, float and double, the expected type of this argument is fmt::Radix.

u32 a = strReader.parse<u32>(fmt::Radix{16});   // parse hex integer such as "badf00d"
u32 b = strReader.parse<u32>(fmt::Radix{2});    // parse binary integer such as "1101101"

For more information, see Parsing Text.

template <typename Format, typename = void_t<decltype(fmt::FormatParser<Format>::parse)>>
auto parse(const Format& format = {}) [code]

A template function to parse text in the format specified by Format. The return type depends on the format being parsed. It currently supports the following built-in formats:

  • fmt::QuotedString

  • fmt::Identifier

  • fmt::Line

  • fmt::WhiteSpace

  • fmt::NonWhiteSpace

    strReader.parse<fmt::WhiteSpace>(); // returns nothing; whitespace is skipped

This function accepts an optional argument format of type Format. When this argument is passed, you can leave out the function template argument and let the compiler deduce it from the argument type:

bool success = strReader.parse(fmt::QuotedString{fmt::AllowSingleQuote});

You can extend this function to support additional formats by specializing the fmt::FormatParser class template.

For more information, see Parsing Text.

template <typename Type>
String readString(const decltype(fmt::TypeParser<Type>::defaultFormat())& format = fmt::TypeParser<Type>::defaultFormat()) [code]
template <typename Format, typename = void_t<decltype(fmt::FormatParser<Format>::parse)>>
String readString(const Format& format = {}) [code]

These functions are similar to the family of parse() functions, except that they return a String containing the input that was consumed by the parse operation. For example, readString<fmt::Line>() returns a single line of text terminated by '\n'.

String line = strReader.readString<fmt::Line>();

Internally, readString() uses getCursor() to return a new String. If you would like both the String and the value returned by the parse function, you can use getCursor() yourself:

ChunkCursor startCursor = strReader.getCursor();
u32 value = strReader.parse<u32>();
String str = String::fromChunks(std::move(startCursor), strReader.getCursor());
String readRemainingContents() [code]

Reads all the remaining data from the input stream and returns the contents as a String.

StringView viewAvailable() const [code]

Reads all the remaining data from the input stream and returns the contents as a String.

Members Inherited From ply::InStream

  • u8* curByte
  • u8* endByte
  • InStream()
  • InStream(InStream&& other)
  • InStream(OptionallyOwned<InPipe>&& inPipe, u32 chunkSizeExp = DefaultChunkSizeExp)
  • void operator=(InStream&& other)
  • bool isView() const
  • bool atEOF() const
  • s32 numBytesAvailable() const
  • ConstBufferView viewAvailable() const
  • u64 getSeekPos() const
  • ChunkCursor getCursor() const
  • void rewind(ChunkCursor cursor)
  • u32 tryMakeBytesAvailable(u32 numBytes = 1)
  • char peekByte(u32 index = 0) const
  • void advanceByte(u32 numBytes = 1)
  • u8 readByte()
  • bool read(BufferView dst)
  • Buffer readRemainingContents()
  • ViewInStream* asViewInStream()
  • const ViewInStream* asViewInStream() const
  • StringReader* asStringReader()
  • StringViewReader* asStringViewReader()